[Из песочницы] Введение в Size Classes в xCode 6
Привет всем! Сегодня хотелось бы сделать небольшое введение в такую штуку, как Size Classes. Она появилась недавно вместе с Xcode 6, документации по ней от самой Apple совсем немного.Итак, для чего же предназначена Size Classes? Все мы знаем, что на подходе уже iPhone 6 двумя (как минимум) разными размерами дисплея (4,7 и 5,5), после чего разработчикам еще больше придется заморачиваться с версткой UI для них + само собой расширения iPad«ов. В итоге количество всех поддерживаемых экранов будет около 7 (маленький привет Android). Герой сегодняшнего дня — Size Classes — как раз и предназначен для того, что бы помочь решить данную проблему.Создадим тестовый пример в Xcode 6. Выбирем SingleViewApplication, в пункте Devices ставим Universal:
Далее выбираем наш Main.storyboard и в вкладке File Inspector ставим галочку напротив Use Size Classes (если она не выбрана по умолчанию):
Теперь обратим внимание на наш storyboard, он не совсем такой, каким мы привыкли его видеть:
После того, как был выбран Use Size Classes, ViewController принял некий абстрактный (базовый) размер, с обозначением wAny hAny (любая высота, любая ширина) о которой поговорим чуть дальше.
Немного теории. Каждый созданый ViewController имеет свой UITraitCollection объект (предоставляющий подробную информацию о характеристиках ViewController), который в свою очередь имеет 2 Size Class: горизонтальный и вертикальный. Каждый Size Class может иметь 3 возможных значения: компактный (compact), обычный (regular) и любой (any). Эти значения изменяются в зависимости от устройства, а также его ориентации. Тоесть, приложение будет иметь свой отдельный интерфейс для каждого ViewController основываясь на текущих Size Class.
Возвращаясь к нашему wAny hAny, что же это? Это не что иное как сетка выбора конфигурации, для работы с определенным типом устройства, которая выглядит следующим образом:
При наведении курсора на сетку Apple дает подсказки разработчику при каких размерах какие устройства имеются ввиду. Общая картина сетки выглядит таким образом:
Базовые значения (any Width | any Height):
iPhone ландшафтный режим (compact Width | compact Height):
iPhone портретный режим (compact Width | regular Height):
iPad ландшафтный и портретный режим (regular Width | regular Height):
Нужно обратить внимание на зеленые точки посредине каждого квадрата сетки. Они показывают к каким устройствам будут применены изменения, которые вы делаете в данной конфигурации. Например, при базовых значениях (any Width | any Height) точки показывают разработчику что изменения будут применятся ко всем типам устройств. По этой причине Apple, рекомендует делать большую часть работы с интерфейсом именно в этой конфигурации.
Вернемся к нашему тестовому примеру. Как было сказано выше сейчас у нашего ViewController базовый Size Class (any Width | any Height). Добавим на наш ViewController 3 простых View размером 100 на 100, окрасив их в зеленый цвет, также добавим UILabel и UIButton шириной 600 и высотой 50 также окрасив их для наглядности:
Добавим Constraints: кнопке — центрирование по вертикали и горизонтали, а также Height и Wight.трем View — Height и Wight, Horizontal space и Vertical Space. Тоже самое проделаем и с UILabel.
В итоге наш ViewController вместе с Constraints будет иметь следующий вид:
Запустим наше приложение на выполнение на iPhone 5 portrait и landscape:
и iPad 2:
Как видим результат не очень утешный, на iPhone 5 portrait две вью вылезли непонятно куда, в landscape режиме с размерами вьюх и лейбла просто беда, а их ширина через чур велика. В iPad все не так страшно, но расстояние между лейблом и кнопкой слишком большое, а первая UIView растянулась.
Сначала исправим все для iPhone 5. Для начала в Size Classes выберем (compact Width | regular Height) для портретной ориентации:
Обратите внимание что полоска выбора Size Classes стала синей. Это говорит о том, что бы вы были повнимательней, так как на данный момент находитесь не в базовой конфигурации, и изменения 4х типов будут применимы только к данному типу и ориентации устройства. Какие же это изменения? Как было сказано их 4:
1) значения Constraint’ов2) шрифты3) включение/выключение Constraint’ов4) включение/выключение subviews
P.S. Напомним, все что будет далее сделано, применимо ТОЛЬКО к портретной ориентации iPhone 5, о чем нас информирует зеленая точка в сетке Size Classes!
Начнем с 1 пункта и исправим значения Constraint, что бы все выглядело корректно. В данной конфигурации мы видим ошибки Constraint:
Для их исправления в данной ориентации идем к настройкам Constraint, и выберем значение горизонтального расстояния между View так как для iPhone оно слишком большое:
В панели Utilities в вкладке Size Inspector возле пункта Constant (а также возле «Installed», но о нем позже) жмем небольшой знак »+»:
И выбираем «Compact Width | Regular Height (current)»:
Видим, что у нас появилась новая Constant (wC hR), для данной ориентации, введем значение 34. Тоже самое проделываем со вторым Constraint между 2й и 3й вью.
После чего у нас должны исчезнуть ошибки связанные с расстоянием по ширине между вью:
Тоже самое проделаем и с шириной кнопки и лейбла для данной ориентации. Выберем их ширину, добавим Constant «Compact Width | Regular Height (current)», и установим значение 200:
Как мы помним, нашей кнопке мы устанавливали Horizontal Center in Container и Vertical Center in Container, от чего и возникают оставшиеся конфликты. Их можно решить как минимум 2 способами в зависимости от того что требуется, 1й способ, разместить кнопку по центру как она того и требует, либо оставить все как есть и воспользоваться 3 пунктом из списка выше. В данном примере мы воспользуемся способом под номером 2, так как это все таки статья о Size Classes.
Итак, для того чтобы «выключить» Constraint, которая нам мешает, нужно ее выбрать из списка:
И снова обратиться к вкладке Size Inspector, только теперь нажимаем »+» который возле чекбокса «Installed»:
Опять таки выбираем и выбираем «Compact Width | Regular Height (current)», и теперь у нас как и с Constant (wC hR) появился чекбокс wC hR «Installed», убираем его и видим, что ошибки исчезли, а для данной конфигурации данный Constrain выключен:
Запустим наше приложение на выполнение и увидим, что все отображается корректно (ну почти все, так как размеры View не подгонялись для конкретного устройства Xcode автоматически уменьшает одну из них):
Данную проблему мы исправим позже.
Проделываем аналогичные действия для iPhone 5 landscape, выберем в сетке Size Classes (compact Width | compact Height):
Нам нужно так как и для портретного режима изменить расстояние между вью и размеры кнопки и лейбла, я выбрал такие же значения как и для портретного режима: расстояние между вью 34, размер кнопки и лейбла 200. Запустим наш апп:
Опять таки из за того, что мы не подгоняли размер, Xcode растягивает View. Исправим эту ошибку в портретной (compact Width | regular Height) и ландшафтной (compact Width | compact Height) ориентации. Выделим наши 3 вьюхи и выбираем в меню Editor → Pin → Widths Equally. После чего запустим наше приложение на выполнение и видим что все отображается корректно:
Дабы не повторяться для iPad, мы проделываем все тоже самое, что и для iPhone, только в сетке Size Classes выбираем regular Width | regular Height, что соответствует портретной и ландшафтной ориентации iPad. В данной ситуации мы просто обновили все Constraint, отцентрировали и выставили Width, Height Equally:
Осталось 2 пункта, по которым не прошлись, это включение/выключение subviews и шрифты. Выберем ландшафтный режим iPhone compact Width | compact Height. Выделим наш UILabel и перейдем в Attributes Inspector, напротив шрифта мы увидим уже знакомый нам »+»:
По аналогии с Constraint добавляем «compact Width | compact Height (current)». Для значения wC hC выставим шрифт Helvetica Neue Ultra Light и размер 23. При запуске мы увидим что в портретной ориентации шрифт стандартный, а уже в ландшафте Helvetica Neue:
Итак, последний пункт это включение и выключение subviews. Я думаю, тут объяснять уже ничего не надо, и так все становится понятно после всех этих разжовываний. Все по аналогии с включением выключением Constraint, разница лишь только в том, что тут мы выключим кнопку для конкретной ориентации:
В общем, моя первая статья получилась не маленькая, но и небольшая, надеюсь, она интересная и полезная. На момент написания статьи Xcode 6 еще в бете, и не выпущен iPhone 6, после презентации которого возможно пополнится документация, а также изменится и внешний вид ViewController’ов в storyboard, так как в данной ситуации не очень удобно все размещать в «квадратах», хотя в сетке Size Classes выбран iPhone landscape.
По материалам: developer.apple.com/library/prerelease/ios/recipes/xcode_help-IB_adaptive_sizes/EnablingAdaptiveSizeDesign.html#//apple_ref/doc/uid/TP40014436-CH1-SW1
Спасибо за внимание!