когда использовать раскадровку и когда использовать xib

<p>существуют ли какие-либо рекомендации относительно того, когда использовать раскадровки в проекте ios и когда использовать xib? каковы плюсы и минусы каждого из них и какие ситуации им подходят?</p><p>насколько я могу судить, использование сегментированных раскадровок не так уж и чисто, когда контроллеры представления выталкиваются динамическими элементами пользовательского интерфейса (например, контактами карты).</p>

<p>я широко использовал xib и выполнил два проекта, используя раскадровки. мои уроки:</p><ul> <li>раскадровки хороши для приложений с небольшим или средним количеством экранов и относительно простой навигацией между представлениями.</li> <li>если у вас много представлений и много перекрестных переходов между ними, представление раскадровки становится запутанным и слишком много работы для поддержания чистоты.</li> <li>для большого проекта с несколькими разработчиками я бы не использовал раскадровки, потому что у вас есть один файл для пользовательского интерфейса и вы не можете легко работать параллельно.</li> <li>возможно, стоит разбить большие приложения на несколько файлов раскадровки, но я этого не пробовал. <a href="https://stackoverflow.com/a/9610972/937822">этот ответ</a> показывает, как делать переходы между раскадровками.</li> <li>вам все еще нужны xib: в обоих моих проектах раскадровки мне приходилось использовать xib для пользовательских ячеек таблицы.</li> </ul><p>я думаю, что раскадровки - это шаг в правильном направлении для реализации пользовательского интерфейса, и надеюсь, что apple расширит их в будущих версиях ios. однако им необходимо решить проблему "одного файла", иначе они не будут привлекательны для более крупных проектов.</p><p>если бы я запустил приложение небольшого размера и мог позволить себе совместимость только с ios5, я бы использовал раскадровки. во всех остальных случаях я придерживаюсь xib.</p>

<p><strong> обновление от 12.01.2016 </strong>: сейчас 2016 год, и я все еще предпочитаю размещать свои интерфейсы в коде, а не в раскадровке. при этом раскадровки прошли долгий путь. я удалил из этого поста все пункты, которые больше не применяются в 2016 году.</p><p><strong> обновление 24.04.2015 </strong>: интересно, что apple даже не использует раскадровки в своем недавно открытом исследовательском наборе researchkit как <a href="http://petersteinberger.com/blog/2015/researching-researchkit/">заметил питер штейнбергер</a> (под заголовком "интерфейсный конструктор").</p><p><strong> обновление 6/10/2014 </strong>: как и ожидалось, apple продолжает улучшать раскадровки и xcode. некоторые из пунктов, которые применяются к ios 7 и ниже, больше не применяются к ios 8 (и теперь помечены как таковые). таким образом, хотя раскадровки по-прежнему имеют недостатки, я пересмотрю свой совет с <strong> <em> не используйте </em> </strong> до <strong> <em> выборочно использовать там, где это имеет смысл </em> </strong>.</p><p>даже сейчас, когда ios 9 вышла, я бы посоветовал <del>против</del> проявлять осторожность при принятии решения об использовании раскадровки. вот мои причины:</p><ul> <li> <p><strong> раскадровки дают сбой во время выполнения, а не во время компиляции </strong>: у вас есть опечатка в имени segue или вы неправильно ее связали в раскадровке? это взорвется во время выполнения. вы используете пользовательский подкласс uiviewcontroller, которого больше нет в вашей раскадровке? это взорвется во время выполнения. если вы делаете такие вещи в коде, вы поймаете их на раннем этапе, во время компиляции. <strong> <em> обновление </em> </strong>: мой новый инструмент <strong> <a href="https://github.com/jfahrenkrug/storyboardlint">storyboardlint</a> </strong> в основном решает эту проблему.</p> </li> <li> <p><strong> раскадровки быстро сбиваются с толку </strong>: по мере роста вашего проекта навигация по раскадровке становится все более сложной. кроме того, если несколько контроллеров представления имеют несколько переходов к нескольким другим контроллерам представления, ваша раскадровка быстро начинает выглядеть как чаша спагетти, и вы обнаружите, что увеличиваете и уменьшаете масштаб и прокручиваете всюду, чтобы найти контроллер представления, который вы ищете для и выяснить, что segue указывает, где. <strong> <em> обновление </em> </strong>: эту проблему в основном можно решить, разделив раскадровку на несколько раскадровок, как описано в <a href="http://pilky.me/37/">эта статья пилки</a> и <a href="http://robsprogramknowledge.blogspot.pt/2012/01/uistoryboard-best-practices.html">эта статья роберта брауна</a> .</p> </li> <li> <p><strong> раскадровки усложняют работу в команде </strong>: поскольку у вас обычно есть только один огромный файл раскадровки для вашего проекта, если несколько разработчиков регулярно вносят изменения в этот файл, это может быть головной болью: изменения должны быть объединены и конфликты разрешены. когда возникает конфликт, трудно сказать, как его разрешить: xcode генерирует xml-файл раскадровки, и он на самом деле не был разработан с той целью, чтобы человеку пришлось читать, не говоря уже о его редактировании.</p> </li> <li> <p><strong> раскадровки делают проверку кода трудной или почти невозможной </strong>: рецензирование кода коллег - отличная вещь для вашей команды. однако, когда вы вносите изменения в раскадровку, практически невозможно просмотреть эти изменения у другого разработчика. все, что вы можете получить - это разбор огромного xml-файла. расшифровать то, что действительно изменилось, и если эти изменения верны или они что-то сломали, действительно сложно.</p> </li> <li> <p><strong> раскадровки препятствуют повторному использованию кода </strong>: в моих проектах ios я обычно создаю класс, который содержит все цвета, шрифты, поля и вставки, которые я использую в приложении чтобы придать ему единообразный вид: изменение в одну строку, если мне нужно настроить любое из этих значений для всего приложения. если вы устанавливаете такие значения в раскадровке, вы дублируете их, и вам нужно будет найти каждый случай, когда вы захотите изменить их. скорее всего, вы пропустите один, потому что в раскадровке нет поиска и замены.</p> </li> <li> <p><strong> раскадровки требуют постоянных переключателей контекста </strong>: я работаю и ориентируюсь в коде гораздо быстрее, чем в раскадровках. когда ваше приложение использует раскадровки, вы постоянно переключаете свой контекст: "о, я хочу нажать на эту ячейку табличного представления, чтобы загрузить другой контроллер представления. теперь мне нужно открыть раскадровку, найти правильный контроллер представления, создать новый переход". другому контроллеру представления (который я также должен найти), дайте имя segue, запомните это имя (я не могу использовать константы или переменные в раскадровках), переключитесь обратно на код и надеюсь, что я не опечатал имя что за мой метод prepareforsegue. как бы я хотел, чтобы я мог просто ввести эти 3 строки кода прямо здесь, где я нахожусь! нет, это не весело. переключение между кодом и раскадровкой (а также между клавиатурой и мышью) устареет и замедляет работу.</p> </li> <li> <p><strong> раскадровки трудно реорганизовать </strong>: когда вы реорганизуете свой код, вы должны убедиться, что он по-прежнему соответствует ожидаемому. когда вы перемещаете вещи в своей раскадровке, вы только узнаете во время выполнения, работает ли он с вашим кодом. мне кажется, что мне нужно синхронизировать два мира. это чувствует себя хрупким и препятствует изменениям в моем скромном мнении.</p> </li> <li> <p><strong> раскадровки менее гибкие </strong>: в коде вы можете делать все, что захотите! с раскадровками вы ограничены подмножеством того, что вы можете делать в коде. особенно, если вы захотите сделать некоторые сложные вещи с анимацией и переходами, вы обнаружите, что "боретесь с раскадровкой", чтобы заставить ее работать.</p> </li> <li> <p><strong> раскадровки не позволяют вам изменять тип специальных контроллеров представления </strong>: вы хотите изменить <code>uitableviewcontroller</code> на <code>uicollectionviewcontroller</code>? или в простом <code>uiviewcontroller</code>? невозможно в раскадровке. вы должны удалить старый контроллер представления и создать новый и повторно соединить все переходы. гораздо проще сделать такое изменение в коде.</p> </li> <li> <p><strong> раскадровки добавляют к вашему проекту два дополнительных обязательства </strong>: (1) инструмент редактора раскадровки, который генерирует xml раскадровки, и (2) компонент времени выполнения, который анализирует xml и создает объекты пользовательского интерфейса и контроллера из него. обе части могут иметь ошибки, которые вы не можете исправить.</p> </li> <li> <p><strong> раскадровки не позволяют добавлять подпредставление к <code>uiimageview</code> </strong>: кто знает почему.</p> </li> <li> <p><strong> раскадровки не позволяют включить автоматическую компоновку для отдельных представлений (-controller) </strong>: установив/сняв флажок с параметром автоматическая компоновка в раскадровке, изменение применяется ко всем контроллерам в раскадровке. (спасибо сава мазаре за этот пункт!)</p> </li> <li> <p><strong> раскадровки имеют более высокий риск нарушения обратной совместимости </strong>: xcode иногда меняет формат файла раскадровки и не гарантирует, что вы сможете его открыть. файлы раскадровки, которые вы создаете сегодня, через несколько лет или даже месяцев. (спасибо за достижения в этом вопросе. <a href="https://stackoverflow.com/questions/9404471/when-to-use-storyboard-and-when-to-use-xibs/19457257?noredirect=1#comment33341639\_19457257">см. оригинальный комментарий</a> )</p> </li> <li> <p><strong> раскадровки могут сделать ваш код более сложным </strong>: когда вы создаете свои контроллеры представления в коде, вы можете создавать собственные методы <code>init</code>, например <code>initwithcustomer:</code>. таким образом, вы можете сделать <code>customer</code> внутри вашего контроллера представления неизменным и убедиться, что этот контроллер представления не может быть создан без объекта <code>customer</code>. это невозможно при использовании раскадровок. вам нужно будет дождаться вызова метода <code>prepareforsegue:sender:</code>, а затем вам нужно будет установить свойство <code>customer</code> на вашем контроллере представления, что означает, что вы должны сделать это свойство изменяемым, и вы должны будете разрешить создание контроллера представления без объект <code>customer</code>. по моему опыту, это может значительно усложнить ваш код и усложнить процесс рассмотрения вашего приложения. <strong> обновление 9/9/16 </strong>: крис джомбак написал <a href="https://www.dzombak.com/blog/2016/09/fixing-storyboard-segues--only-apple-can-do-this.html">отличная статья об этой проблеме</a> .</p> </li> <li> <p><strong> это mcdonald's </strong>: стив джобс говорит о microsoft: <a href="http://youtu.be/ejwwtv1w5fw?t=1m31s">это mcdonald's (видео)</a> !</p> </li> </ul><p>это мои причины, почему мне действительно не нравится работать с раскадровками. некоторые из этих причин также относятся к xib. в проектах, основанных на раскадровке, над которыми я работал, они стоили мне гораздо больше времени, чем они экономили, и они усложняли, а не упрощали вещи.</p><p>когда я создаю свой пользовательский интерфейс и поток приложений в коде, я гораздо больше контролирую происходящее, легче отлаживать, легче выявлять ошибки на ранних этапах, легче объяснить мои изменения другим разработчикам, и это легче поддерживать iphone и ipad.</p><p>тем не менее, я согласен с тем, что размещение <em> всего вашего пользовательского интерфейса </em> в коде не может быть универсальным решением для каждого проекта. если ваш интерфейс ipad в некоторых местах сильно отличается от вашего интерфейса iphone, возможно, имеет смысл создать xib только для этих областей.</p><p>apple может решить многие описанные выше проблемы, и я надеюсь, что именно так они и будут.</p><p>просто мои два цента.</p><p><strong> обновление </strong>: в xcode 5 apple убрал возможность создать проект без раскадровки. я написал небольшой скрипт, который переносит шаблоны xcode 4 (с опцией storyboard-opt-out) в xcode 5: <a href="https://github.com/jfahrenkrug/xcode4templates">https://github.com/jfahrenkrug/xcode4templates</a> </p>

<p>раскадровки были созданы, чтобы помочь разработчикам визуализировать свое приложение и поток приложения. это очень похоже на кучу xib, но в одном файле.</p><p>есть вопрос, похожий на этот: <a href="https://stackoverflow.com/questions/8436324/what-is-the-difference-between-a-xib-file-and-a-storyboard">в чем разница между .xib-файлом и .storyboard?</a> .</p><p>вы также можете создавать собственные переходы с помощью кода, который будет динамически изменяться при необходимости, так же, как вы можете с .xibs.</p><p>плюсы:</p><ul> <li>вы можете смоделировать поток приложения без особого написания кода.</li> <li>намного легче увидеть ваши переходы между экранами и потоком ваших приложений.</li> <li>также можно использовать .xibs при необходимости с раскадровками.</li> </ul><p>минусы:</p><ul> <li>работает только с ios 5+. не работает с ios4.</li> <li>может легко запутаться, если у вас очень интенсивное приложение.</li> </ul><p>там действительно нет правильного/неправильного, когда использовать один или другой, это просто вопрос предпочтения и какие версии ios вы хотите использовать.</p>

<p>я просто укажу <strong>4 простых причины</strong> почему вы <strong>должны</strong> использовать раскадровки, особенно в продуктивной среде, где вам приходится работать в команде владельцев продуктов, менеджеров продуктов, дизайнеров ux, и т.п.</p><ol> <li><strong>apple значительно улучшила работу со раскадровками.</strong> и они поощряют вас работать с ними. это означает, что они <strong>не будут</strong> ломают ваши существующие проекты обновлениями, они гарантируют, что раскадровки будут перспективными для новых версий xcode/ios.</li> <li><strong>более видимые результаты</strong> в <strong>меньше времени</strong> для владельцев и менеджеров продукта, даже на этапе создания. вы даже можете использовать саму раскадровку как диаграмму последовательности действий и обсуждать ее на собраниях.</li> <li>четный <strong>после того, как приложение готово</strong> (и это, как правило, там, где начинается его жизненный цикл) - в будущем оно будет <strong>быстрее и проще применять небольшие корректировки</strong>. и это вполне может изменить несколько аспектов вашего макета одновременно, что вы, вероятно, захотите увидеть в виде wysiwyg. в качестве альтернативы можно было бы написать изменения в пользовательском интерфейсе, написанные от руки, и переключаться между ide и симулятором для проверки, каждый раз ожидая компиляции и сборки.</li> <li><strong>можно научить не разработчиков</strong> настраивать макеты в раскадровках и создавать необходимые ловушки для разработчиков (iboutlets и ibactions). это очень большой плюс, поскольку он позволяет разработчикам сосредоточиться на логике, а дизайнеры ux применяют свои изменения визуально, без необходимости писать какой-либо код вообще.</li> </ol><p>я не буду писать никаких cons, так как йоханнес уже перечислил, вероятно, все жизнеспособные из них в своем ответе. и большинство из них определенно нежизнеспособны, особенно если не считать значительных улучшений xcode6.</p>

<p>я не думаю, что есть правильный ответ на ваш вопрос, это просто вопрос личного опыта и того, с чем вы чувствуете себя более комфортно.</p><p>на мой взгляд, раскадровки - отличная вещь. это правда, действительно трудно понять, почему ваше приложение таинственно падает во время выполнения, но через некоторое время и опыт вы поймете, что это всегда связано с отсутствием какого-либо iboutlet, и вы легко сможете это исправить.</p><p>единственная реальная проблема - это работа в команде под контролем версий с раскадровками, на ранних стадиях разработки это может быть настоящим беспорядком. но после этого первого этапа обновления пользовательского интерфейса, которые полностью изменяют раскадровку, очень редки, и в большинстве случаев вы сталкиваетесь с конфликтами в самых последних частях xml, которые являются переходными ссылками, которые обычно автоматически исправляются при повторном открытии раскадровки , в нашей командной работе мы предпочитали иметь дело с этим вместо тяжелых контроллеров представления с тоннами кода представления.</p><p>я прочитал много комментариев об авто-макете. с xcode5 он действительно улучшился, он действительно хорош даже для автоматического размещения макетов. в некоторых случаях вам придется что-то делать в коде, но вы можете просто вывести ограничение, которое нужно отредактировать, и в этот момент делать то, что вам нужно в вашем коде. даже оживить их.</p><p>я также думаю, что большинство людей, которым не нравятся раскадровки, не пытались полностью понять всю мощь пользовательского перехода, где вы можете полностью настроить (в одном файле) способ перехода с пути на другой, а также (с помощью некоторые приемы) даже повторно использовать ранее загруженный контроллер представления, просто обновляя его содержимое представления вместо полной перезагрузки всего объекта. в конце вы действительно можете сделать то же самое, что и в коде, но я думаю, что у вас есть лучшее разделение проблем с раскадровками, но я согласен, что во многих случаях им не хватает функций (шрифты, изображение в качестве цветного фона, ecc ... ).</p>

<p>я работал над проектом разумного размера (> 20 сцен на языке раскадровки), и столкнулся со многими ограничениями, и мне приходится неоднократно переходить к документации и поиску в google, чтобы что-то делать.</p><ol> <li> <p>пользовательский интерфейс все в одном файле. даже если вы создаете несколько раскадровок, у вас все равно есть много сцен/экранов в каждой раскадровке. это проблема в средних и больших командах.</p> </li> <li> <p>во-вторых, они не очень хорошо работают с пользовательскими контроллерами контейнеров, которые встраивают другие контроллеры контейнеров и т.д. мы используем mfslidemenu в приложении с вкладками, и сцена имеет таблицу. это почти невозможно сделать с раскадровкой. потратив несколько дней, я прибег к способу xib, где есть полный контроль.</p> </li> <li> <p>ide не позволяет выбирать элементы управления в уменьшенном состоянии. таким образом, в большом проекте, масштабирование в основном для получения высокого уровня обзора и ничего более.</p> </li> </ol><p>я хотел бы использовать раскадровки для небольших приложений с небольшими размерами команд и использовать подход xib для средних и больших групп/проектов.</p>

<p>я не использую storyboard или xib в любом приложении ... но создаю все программно.</p><p><strong>∆ преимущества:</strong></p><p>√ вы можете создавать любые сложные виды пользовательского интерфейса или анимации перехода для <code>uiview</code>.</p><p>√ поддержка всех версий ios. не нужно беспокоиться о <ios 5.</p><p>√ * ваше приложение будет поддерживать все устройства iphone/ipod/ipad в вашем коде.</p><p>√ вы всегда обновляетесь, поскольку знаете код, который всегда будет работать.</p><p>√ * будет работать на любом (новом) устройстве, запущенном - нет необходимости изменять код.</p><p>√ все зависит от вас. в определенном месте вы хотите что-то изменить - не нужно заглядывать в раскадровку или xib. просто найдите его в определенном классе.</p><p>√ последний, но не список - вы никогда не забудете это, как управлять всем программно. это лучшая вещь, потому что вы знаете контроль очень глубоко, чем кто-либо.</p><p><sub>я никогда не нахожу проблемы, если не использую sb или xib, так как у меня все хорошо.</sub></p><p><sub>* если вы установили рамки объекта uikit в соответствии с размером экрана.</sub></p><p><sub>постскриптум если вы до сих пор не сделали этого - вы можете столкнуться с трудностями (или вам может показаться скучным), но как только вы познакомитесь с этим - это действительно candy для вас.</sub></p>

<p>если вы хотите позаботиться о производительности раскадровки, смотрите <a href="http://asciiwwdc.com/2015/sessions/407">wwdc 2015 session 407</a> </p><p> <a href="https://i.stack.imgur.com/tlnov.png"><img src="https://i.stack.imgur.com/tlnov.png" alt="enter image description here"></a> </p><p><strong> время сборки </strong></p><blockquote> <p>когда конструктор интерфейса компилирует раскадровку, он, во-первых, делает две вещи, пытаясь максимизировать производительность вашего приложения, а во-вторых, он также минимизирует количество созданных nib-файлов.</p> <p>если у меня есть контроллер представления с представлением и несколько вложенных представлений, построитель интерфейса, то при сборке я собираюсь создать файл пера для контроллера представления и создать файл пера для представления.</p> <p>наличие отдельных файлов пера для контроллера представления и представления означает, что иерархия представления может быть загружена по требованию.</p> </blockquote><p><strong> время выполнения </strong></p><blockquote> <p>когда вы выделяете экземпляр раскадровки, используя раскадровку ui, api, первоначально все, на что вы выделяете память, - это сам экземпляр раскадровки интерфейса пользователя.</p> <p>нет контроллеров представления пока нет просмотров.</p> <p>когда вы создаете экземпляр вашего начального контроллера представления, он загрузит перо для этого исходного контроллера представления, но, опять же, иерархия представления еще не была загружена, пока кто-то фактически не запросит его.</p> </blockquote>

<p>если вы хотите повторно использовать некоторый интерфейс в нескольких контроллерах представления, вам следует использовать xib</p>