Pull to refresh

Comments 44

>Нельзя все сделать в Storybaord при все желании. Например, задать cornerRadius, shadowOffset

IBInspectable или задавать через user defined runtime attributes (как собственно IBInspectable и работает)

Тема, конечно, холиварная, но раскрыта поверхностно. Вот немного еще по теме www.raywenderlich.com/51992/storyboards-vs-nibs-vs-code-the-great-debate

Хорошо бы рассмотреть варианты в контексте использования size class'ов.
Ну и не забыть про такой важный момент как наглядность верстки.

Считаю, что нужно отталкиваться от задачи. Начинать однозначно со storyboard/xib. Autolayout'ы использовать в коде, когда есть необходимость (а такое, конечно, бывает). На фреймы переходить только в крайнем случае, исключительно для повышения производительности.

С изумлением смотрю на storyboard, который никак не вписывается в современную модульность. Для игр использую xib+*.h+*.m для каждого игрового экрана. И никаких auto. Два xib (*.xib и *_iPad.xib) для каждого ViewController, если игра универсальная.
«И никаких auto» — безе Auto Layout? А как вы на зоопарк диагоналей делаете тогда интерфейс под iPhone?
На сколько понимаю в играх проще задавать относительные значения.
Ну, это как посмотреть, тот же AL позволяет размещать элементы на экране пропорционально сторонам, у меня есть успешный опыт.
Тут интересно именно тем, как сделать тянущийся интерфейс в Storyboard не прибегая к Auto Layout. Особенно на новый айпадах со Split View…
Свободу попугаям! В смысле нет зоопарка. Выкидываю LaunchScreen.xib, предлагаемый по умолчанию, делаю две заставки 640х1136 и 640х960 (их все равно рисовать) и все.
Поскольку доля iPhone 4 мала, я использую один и тот же xib, просто на 4-ке не показываю нижний рекламный баннер) Пусть старички порадуются)
Не нашёл вариант Storyboard + Xib когда в сториборде только навигация, а в ксибах сами контроллеры
Думаю это удобнее, чем если все в Storyboard. Однако, верстать в коде мне кажется более удобным вариантом (тем же PureLayouts).
Честно говоря, при первом прочтении я неправильно как-то понял идею… В чем принципиальное отличие от того, чтоб хранить VIewController в самом Storyboard-е?
В комменте ниже, есть более адекватная замена:
> Для реиспльзуемых элементов можно использовать ContainerView + Embed Segue в storyboard.
> Этот вариант удобней тем, что прямо в storyboard вы настраиваете какой контрой в какое место вставлять, то есть не нужно писать дополнительный код как в случае с xib.
Вы не упомянули вопросы локализации. Interface Builder в этом очень неплохо помогает.
Не могу согласиться с этим утверждением. Во-первых, появляются Base.lproj/en.lproj директории и наш Storyboard среди фалов находить становится трудней. Во-вторых, NSLocalizedString на много удобней. И наконец, если мы удалили View и добавили другую, скажем, с аналогичным содержанием (например, был toolbar решили сделать все в custom view) у нее будет другой идентификатор и, соответственно, ее нужно опять переводить.
Ну по моему опыту — руками делать все в NSLocalizedString можно только до определенного объема, дальше управлять этим хозяйством становится сложно, руками разбивать на различные Tables и так далее. В IB есть еще замечательный Preview, включая «Double-Length Pseudolanguage», как без него тестировать AutoLayout на реакцию на различные переводы?
Как работать с файлами строк локализации, если они меняются постоянно, если меняется структура разметки, идентификаторы и т.п. Пробовал раз — ничего не вышло, пробовал скрипты для инкрементных изменений в переводах — не вышло. Пришел к выводу, что проще в IB вставлять ключи от localizable strings а при загрузке view пробегать по всей иерархии и заменять на тексты из файлов строк…
Можно по подробнее? Где именно вы эти ключи вставляете?
Ну, это еще не апробированный способ, просто решил, что в следующий раз так сделаю.
Прямо в IB в xib и storyboard в текстовые объеты (UILabel, UIButton etc.) вставлять ключи от localizable strings типа «main-screen.cancel».
Потом в loadView или в viewDidLoad пробегаться и заменять уже на NSLocalizableString(...). Как-то так. Если это плохое решение, напишите, я подумаю.
Многие не хотят прописывать ключи в строковые значения из за опасности не перевести их. Тогда пользователь увидит строковый код вместо человеческого английского.
Возможно, для хранения лучше подойдет accessabilityIdentifier, но меня смущает назначение других параметров с аналогичным названием. Например, accessibilityLabel используется слабовидящими для озвучивания элемента.
Хотя, если accessabilityIdentifier используется некоторыми программистами для тестирования, почему бы не использовать его и для локализации?
Если будет упущен в какой-либо части перевод на какой-нибудь язык, то ключи в итоге вылезут в интерфейсе, так как NSLocalizableString вернет ключ, если для него нет значения в строках…
Мне кажется, мой такой пусть пока гипотетический подход более консистентный что ли, чем логический «биндинг» элементов интерфейса в коде… Бывает, что элемент не используется абсолютно никак в логике работы приложения и отвечает только за визуальную часть, но всё равно для перевода требуется делать outlet к нему и переводить в коде руками.

Я пробовал когда-то вот это http://oleb.net/blog/2013/02/automating-strings-extraction-from-storyboards-for-localization/, но не пошло.
Если будет упущен в какой-либо части перевод на какой-нибудь язык, то ключи в итоге вылезут в интерфейсе, так как NSLocalizableString вернет ключ, если для него нет значения в строках…
Если NSLocalizableString возвращает ключ можно не менять текст а оставить значение из IB.
По поводу биндинга полностью согласен. Когда я пришел в iOS из Android, для меня это было дикостью. Но когда, на одной конференции, я узнал что в MailRu применяют этот подход, мой мир вообще рухнул.
> Код с анимациями туда не поместить.
Вообще неплохо решается на кастомных UIStoryboardSegue.

> Если их несколько, то при переходе с одного на другой — создается нагрузка на main thread (NSKeyedArchiver должен распарсить сториборду, а он сам по себе медленный).
Серьезно, несколько переходов между сторибордами не окажут сколько-нибудь значимого влияния на производительность :)

> Нельзя все сделать в Storybaord при все желании. Например, задать cornerRadius, shadowOffset и т.д.
Как уже отмечали выше, IBDesignable, либо User-defined runtime attributes.

Идеальный с точки зрения удобства работы и поддержки вариант — N сториборд + вынесение реиспользуемых элементов в xib'ы. Скатываться в чрезмерную оптимизацию имеет смысл только при наличии фактических проблем с производительносью, при том же скролле сложных таблиц. Лэйаут в коде обычно выглядит понятным только для его автора, а вот остальным приходится тяжелее.
вынесение реиспользуемых элементов в xib'ы

Для реиспльзуемых элементов можно использовать ContainerView + Embed Segue в storyboard.
Этот вариант удобней тем, что прямо в storyboard вы настраиваете какой контрой в какое место вставлять, то есть не нужно писать дополнительный код как в случае с xib.
Это будет работать, например, с ячейками таблиц и коллекшн вью?
Да, все будет работать.

Пример реюзания контроллера с таблицей в двух других (родительских) контроллерах
image
А если из двух разных сторибородов надо одну и ту же вью взять?
Для этих целей можно использовать объект Storyboard Reference. Он позволяет экспортировать контроллеры из одного сториборда в другие.
Правда эта фича доступна только с iOS 8.

Как это выглядит?

Спасибо большое за Cartography! Я так очарован его дизайном, что кажется SnapKit я больше использовать не буду.
Каждая моя попытка использовать Storyboard или XIB заканчивается тем что весь дизайн в нем все равно не настроишь и все равно приходится часть делать в коде, получаем на выходе кашу, часть значений настроена тут, часть тут. Для себя я остановился на ручной верстке с использование autolayout там где это оправдано и autosizing там где важен перформанс. Благо при разработке на rubymotion есть множество библиотек облегчающих именно такой подход и предоставляющих очень элегантные обертки.
в rubymotion можно использовать все то же, что и в cocoa touch, включая xib и storyboard (которые конечно придется рисовать в xcode), есть даже несколько гемов облегчающих жизнь с ними. но по моим ощущениям они особой популярностью не пользуются, может быть потому, что нет интеграции с редактором кода и связи IBOutlet приходится руками создавать.
Просмотрел rubymotion по диагонали — вещь конечно интересная, но ruby лишен типизации, а это, на мой взгляд, очень серьезная беда. Там свои свой рантайм (не MRI), но есть ли там типизация я не понял. Не могли бы прояснить?

К тому же нет protocol-ов — это совсем плохо… Как вы без них живете? или они есть?
На самом деле идологически ruby и objective c достаточно близки. В обоих языках методы это все го лишь функции и вызов осуществляется отправкой сообщения, что позволяет в рантайме добавлять методы или даже подменять существующие.

Типов нет, это язык динамический этапа присвоения (т.е. тип прозрачно назначается в момент присвоения значения). Нельзя сказать что это плохо, это просто другой подход, дающий очень очень большую свободу но и несущий определнный риск.

Протоколов в самом руби нет, т.к. они просто не нужны. Вместо того чтобы говорит «дай мне объект реализующий такой то протокол», в руби всегда можно проверить «а вот эта балалайка поймет если я позову у нее метод :abc? нет? ну значит кинем exception».

В общем rubymotion позволяет писать приложение намного быстрее (особенно если вы хорошо знаете ruby) благодаря огромной гибкости языка и наличию большого количества библиотек, которые скрывают за собой сложности Cocoa в тех случая когда они не нужны.
Язык ruby я знаю достаточно хорошо, и с крутостью рантаймов ruby/objc (идеологических аналогов smalltalk) тоже знаком. Но такая гибкость часто выходит боком — слишком многое приходится хранить в своей голове. Тогда как при строгой типизации — компилятор очень часто спасает от запоминания типов функций, переменных и тд.

Есть такая штука protocol-oriented programming, которая мне очень нравится, особенно в swift 2. К тому же я не могу себе представить более или менее гибкую архитектуру без абстрактных интерфейсов (т.е. protocol).

Не буду разводить холивар, но мне комфортней работать со статической типизацией. Я никого к этом не призываю, просто мне так удобнее.

Есть ли руби с типами?
По-моему при более-менее сложном дизайне — ручная верстка превратится в ад. Все-таки мышью и красивее и нагляднее, и что-то поменять можно в 2 клика.

Другой вопрос, что для видимо для некоторых разработчиков, перешедших в iOS из web-а, такой подход вполне привычный. Но по сути это имхо позавчерашний день, сродни написанию кода в notepad-e и уверению всех что это круто.

Главный минус storyboard для меня, это сложность с командной работой, в этом плане XIB еще долго будет жить. А насчет скорости, честно говоря не понял, в каких задачах распаковка из NIB будет узким местом? Есть ли какие-то реальные замеры где что-то тормозило бы, или это оптимизация ради оптимизации?

Имхо 95% поведения viewcontroller-a может быть задано в storyboard (constrains, size-classes), оставшиеся 5% можно и закодить.
Главный минус storyboard для меня, это сложность с командной работой

Можете пояснить в чем сложность использования storyboard в случае командной работы?
Storyboard это не тот формат файлов, где было бы удобно исправлять конфликты в git :)

Кстати только вчера попробовал после этой статьи, хранить связи в storyboard а сам диалог в xib, загружая его в loadView, вполне работает. Т.е. вполне можно совмещать визуальную наглядность связей storyboard и легкость раздельного редактирования ресурсов.
Я спросил к тому, что формат сторибордов и xib был сильно улучшен в последних версиях Xcode (стал более читаемым и структурированным). У нас в команде достаточно редко возникают конфликты при одновременном изменении сториборда (на проекте 4 человека).
Конфликты возникают, когда несколько разработчиков одновременно меняют один и тот же контроллер. Но это те же конфликты, что и в случае с отдельным xib для каждого контроллера.
Если их несколько, то при переходе с одного на другой — создается нагрузка на main thread (NSKeyedArchiver должен распарсить сториборду, а он сам по себе медленный).

В скомпилированном виде сториборд представляет из себя набор nib-файлов и небольшого файлика с метаданными. То есть при создании инстанса UIStoryboard «распарсить» надо только метаданные. А грузить при переходе VC из nib-файла придется в любом случае, даже если сториборд у вас один.
Хм, понятно. Дело в том, что при загрузке сториборды у нас, по не очевидной причине анимация дергалась. Я во всем винил процесс декодирования, видимо, зря…
Я бы сказал что сейчас стоит использовать (и вообще задумываться) о ручной верстке в двух случаях:

1. Когда требуется что-то что нельзя задать в рамках Auto Layout, но с таким я сталкивался всего два раза.
2. Требуется считать раскладку очень быстро, например, множество сложных ячеек в таблице.

Во всех остальных случаях ручная верстка дает больше проблем чем пользы, как правильно заметил автор очень много кода, который потом еще надо и как-то поддерживать.
Самый жирный минус сториборда — невозможность нормального merge при совместной разработке. Xib мержить немного проще (за счет того, что там обычно вьюхи для каждого отдельного вьюконтроллера).
Это по большей части решается использованием нескольких сторибордов.

Существуют ли SizeClasses при ручной верстке с autolayout? Или они существуют только в Storyboard-ах и xib-ах? Чем их можно заменить при ручной верстке?

Sign up to leave a comment.

Articles