Pull to refresh

Введение в Size Classes в Xcode 6

Reading time 6 min
Views 61K
Привет всем! Сегодня хотелось бы сделать небольшое введение в такую штуку, как Size Classes. Она появилась недавно вместе с Xcode 6, документации по ней от самой Apple совсем немного.

Итак, для чего же предназначена Size Classes? Все мы знаем, что на подходе уже iPhone 6 двумя (как минимум) разными размерами дисплея (4,7 и 5,5), после чего разработчикам еще больше придется заморачиваться с версткой UI для них + само собой расширения iPad«ов. В итоге количество всех поддерживаемых экранов будет около 7 (маленький привет Android). Герой сегодняшнего дня — Size Classes — как раз и предназначен для того, что бы помочь решить данную проблему.

Создадим тестовый пример в Xcode 6. Выбирем SingleViewApplication, в пункте Devices ставим Universal:

image

Далее выбираем наш Main.storyboard и в вкладке File Inspector ставим галочку напротив Use Size Classes (если она не выбрана по умолчанию):

image

Теперь обратим внимание на наш storyboard, он не совсем такой, каким мы привыкли его видеть:

image

После того, как был выбран Use Size Classes, ViewController принял некий абстрактный (базовый) размер, с обозначением wAny hAny (любая высота, любая ширина) о которой поговорим чуть дальше.

Немного теории. Каждый созданый ViewController имеет свой UITraitCollection объект (предоставляющий подробную информацию о характеристиках ViewController, доступен с iOS 8, подробней можно почитать тут), который в свою очередь имеет 2 Size Class: горизонтальный и вертикальный. Каждый Size Class может иметь 3 возможных значения: компактный (compact), обычный (regular) и любой (any). Эти значения изменяются в зависимости от устройства, а также его ориентации. Тоесть, приложение будет иметь свой отдельный интерфейс для каждого ViewController основываясь на текущих Size Class.

Возвращаясь к нашему wAny hAny, что же это? Это не что иное как сетка выбора конфигурации, для работы с определенным типом устройства, которая выглядит следующим образом:

image

При наведении курсора на сетку Apple дает подсказки разработчику при каких размерах какие устройства имеются ввиду. Общая картина сетки выглядит таким образом:

Базовые значения (any Width | any Height):

image

iPhone ландшафтный режим (compact Width | compact Height):

image

iPhone портретный режим (compact Width | regular Height):

image

iPad ландшафтный и портретный режим (regular Width | regular Height):

image

Нужно обратить внимание на зеленые точки посредине каждого квадрата сетки. Они показывают к каким устройствам будут применены изменения, которые вы делаете в данной конфигурации. Например, при базовых значениях (any Width | any Height) точки показывают разработчику что изменения будут применятся ко всем типам устройств. По этой причине Apple, рекомендует делать большую часть работы с интерфейсом именно в этой конфигурации.

Вернемся к нашему тестовому примеру. Как было сказано выше сейчас у нашего ViewController базовый Size Class (any Width | any Height). Добавим на наш ViewController 3 простых View размером 100 на 100, окрасив их в зеленый цвет, также добавим UILabel и UIButton шириной 600 и высотой 50 также окрасив их для наглядности:

image

Добавим Constraints:
кнопке — центрирование по вертикали и горизонтали, а также Height и Wight.
трем View — Height и Wight, Horizontal space и Vertical Space. Тоже самое проделаем и с UILabel.

В итоге наш ViewController вместе с Constraints будет иметь следующий вид:

image

Запустим наше приложение на выполнение на iPhone 5 portrait и landscape:

image
image

и iPad 2:
image

Как видим результат не очень утешительный, на iPhone 5 portrait две вью вылезли непонятно куда, в landscape режиме с размерами вьюх и лейбла просто беда, а их ширина чересчур велика. В iPad все не так страшно, но расстояние между лейблом и кнопкой слишком большое, а первая UIView растянулась.

Сначала исправим все для iPhone 5. Для начала в Size Classes выберем (compact Width | regular Height) для портретной ориентации:

image

Обратите внимание, что полоска выбора Size Classes стала синей. Это говорит о том, что бы вы были повнимательней, так как на данный момент находитесь не в базовой конфигурации, и изменения 4х типов будут применимы только к данному типу и ориентации устройства. Какие же это изменения? Как было сказано, их 4:

1) значения Constraint'ов
2) шрифты
3) включение/выключение Constraint'ов
4) включение/выключение subviews

P.S. Напомним, все что будет далее сделано, применимо ТОЛЬКО к портретной ориентации iPhone 5, о чем нас информирует зеленая точка в сетке Size Classes!

Начнем с 1 пункта и исправим значения Constraint, что бы все выглядело корректно. В данной конфигурации мы видим ошибки Constraint:

image

Для их исправления в данной ориентации идем к настройкам Constraint, и выберем значение горизонтального расстояния между View так как для iPhone оно слишком большое:

image

В панели Utilities в вкладке Size Inspector возле пункта Constant (а также возле „Installed“, но о нем позже) жмем небольшой знак „+“:

image

И выбираем „Compact Width | Regular Height (current)“:

image

Видим, что у нас появилась новая Constant (wC hR), для данной ориентации, введем значение 34. Тоже самое проделываем со вторым Constraint между 2й и 3й вью.

image

После чего у нас должны исчезнуть ошибки связанные с расстоянием по ширине между вью:

image

Тоже самое проделаем и с шириной кнопки и лейбла для данной ориентации. Выберем их ширину, добавим Constant „Compact Width | Regular Height (current)“, и установим значение 200:

image

Как мы помним, нашей кнопке мы устанавливали Horizontal Center in Container и Vertical Center in Container, от чего и возникают оставшиеся конфликты. Их можно решить как минимум 2 способами в зависимости от того что требуется, 1й способ, разместить кнопку по центру как она того и требует, либо оставить все как есть и воспользоваться 3 пунктом из списка выше. В данном примере мы воспользуемся способом под номером 2, так как это все таки статья о Size Classes.

Итак, для того чтобы „выключить“ Constraint, которая нам мешает, нужно ее выбрать из списка:

image

И снова обратиться к вкладке Size Inspector, только теперь нажимаем „+“ который возле чекбокса „Installed“:

image

Опять таки выбираем и выбираем „Compact Width | Regular Height (current)“, и теперь у нас как и с Constant (wC hR) появился чекбокс wC hR „Installed“, убираем его и видим, что ошибки исчезли, а для данной конфигурации данный Constrain выключен:

image

Запустим наше приложение на выполнение и увидим, что все отображается корректно (ну почти все, так как размеры View не подгонялись для конкретного устройства Xcode автоматически уменьшает одну из них):

image

Данную проблему мы исправим позже.

Проделываем аналогичные действия для iPhone 5 landscape, выберем в сетке Size Classes (compact Width | compact Height):

image

Нам нужно так как и для портретного режима изменить расстояние между вью и размеры кнопки и лейбла, я выбрал такие же значения как и для портретного режима: расстояние между вью 34, размер кнопки и лейбла 200. Запустим наш апп:

image

Опять таки из за того, что мы не подгоняли размер, Xcode растягивает View. Исправим эту ошибку в портретной (compact Width | regular Height) и ландшафтной (compact Width | compact Height) ориентации. Выделим наши 3 вьюхи и выбираем в меню Editor -> Pin -> Widths Equally. После чего запустим наше приложение на выполнение и видим что все отображается корректно:

image
image

Дабы не повторяться для iPad, мы проделываем все тоже самое, что и для iPhone, только в сетке Size Classes выбираем regular Width | regular Height, что соответствует портретной и ландшафтной ориентации iPad. В данной ситуации мы просто обновили все Constraint, отцентрировали и выставили Width, Height Equally:

image
image

Осталось 2 пункта, по которым не прошлись, это включение/выключение subviews и шрифты. Выберем ландшафтный режим iPhone compact Width | compact Height. Выделим наш UILabel и перейдем в Attributes Inspector, напротив шрифта мы увидим уже знакомый нам „+“:

image

По аналогии с Constraint добавляем „compact Width | compact Height (current)“. Для значения wC hC выставим шрифт Helvetica Neue Ultra Light и размер 23. При запуске мы увидим что в портретной ориентации шрифт стандартный а уже в ландшафте Helvetica Neue:

image
image

Итак, последний пункт это включение и выключение subviews. Я думаю, тут объяснять уже ничего не надо, и так все становится понятно после всех этих разжовываний. Все по аналогии с включением выключением Constraint, разница лишь только в том, что тут мы выключим кнопку для конкретной ориентации:

image
image

В общем, моя первая статья получилась не маленькая, но и небольшая, надеюсь, она интересная и полезная. На момент написания статьи 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

Спасибо за внимание!
Tags:
Hubs:
+17
Comments 19
Comments Comments 19

Articles