antonio's blog

antonio's blog


Блог о всяком разном, связанном с разработкой ПО. Пишу редко, когда есть время и желание.

Anton Dobkin
Author

Share


Tags


AutoLayout в iOS. Часть 1

Anton DobkinAnton Dobkin

Помимо других интересных возможностей, в iOS 6 SDK был добавлен новый механизм расположения пользовательских элементов на экране, который называется AutoLayout (автомакет, автокомпановка).

AutoLayout используется для построения динамических пользовательских интерфейсов, масштабируемых и адаптируемых к различным форматам и разрешениям экранов устройств, а также их ориентациям. AutoLayout пришел на смену системе «пружин и растяжек» применяемую в предыдущих версиях iOS SDK.

Также AutoLayout делает интернационализацию более простой задачей, размещать текст переменной длины на экране становится проще, также поддерживаются языки с направлением письма справа налево, такие как иврит и арабский

Для Mac OS X разработчиков AutoLayout уже знаком, впервые он появился в OS X Lion.

Скачать PDF можно с:

Связи

Работа AutoLayout основана на связях(constraints), которые устанавливают геометрические отношения между представлениями пользовательского интерфейса. Например, мы можем создать связь которая говорит: «текстовая метка должна быть закреплена, на некотором расстоянии от левого края родительского представления и соединена с левым краем кнопки, с добавление между ними промежутка в 10 px» .

AutoLayout берет заданные связи и математически вычисляет идеальные позиции и размеры для всех представлений. Нам не нужно больше устанавливать размеры представлений вручную, задавать их координаты расположения - AutoLayout берет эту работу на себя.

Создавать связи можно как программно, так и с помощью Interface Builder.

Interface Builder

Лучший способ, чтобы понять как работает AutoLayout и приобрести навыки работы с ним - это «поиграться». Начнем знакомство с AutoLayout с простого примера.

Создадим в XCode 4.5 новый Single-View проект с названием «autolayout».

В новых проектах, создаваемых в XCode 4.5, AutoLayout включен по умолчанию и при создании пользовательского интерфейса в Interface Builder, часть связей устанавливается автоматически.

C помощью редактора интерфейсов создадим простой пользовательский интерейс. В менеджере файлов проекта, в левой панели, выбираем файл ViewController.xib и добавляем элементы: «Text Label» и «Text View». Элементы располагаем как показано на рисунке:

Когда мы создавали пользовательский интерфейс и располагали на нем элементы, Interface Builder автоматически создавал связи. Посмотреть созданные связи можно выбрав элемент, например, выберем элемент «Text View»:

Как вы можете видеть, Interface Builder создал четыре связи, они обозначены голубыми линиями. Две связи закрепление левого и правого края текстового представления, относительно основного представления, на расстоянии используемом по умолчанию. Третья связь - выравнивание верхнего края текстового поля относительно основанного представления. И последняя, четвертая, связь - высота текстового представления.

У каждой связи есть свойства. Выберите элемент и перейдите на вкладку «Инспектор размеров» («Size Inspector») на панели «Utils». В секции «Constraints» представлены связи выбранного элемента:

Раскройте меню у «Leading Space to: Superview» и выберите действие «Select and Edit...» для редактирования свойств:

Как видно из следующего рисунка, выбранная нами связь имеет следующие свойства:

Мы не будем сейчас останавливается на рассмотрении свойств, к ним мы еще вернемся.

Соберем и запустим наш проект на симуляторе. Когда симулятор с нашим приложением запустится, переверните устройство в портретную ориентацию (⌘cmd + →(стрелка вправо)), чтобы посмотреть AutoLayout в действии.

Мы видим, что при смене ориентации устройства пользовательский интерфейс автоматически адаптируется.

В данном примере мы проделали очень примитивные действия, которые можно было сделать используя старую систему «пружин и растяжек».

Немного усложним задачу. Допустим, мы хотим чтобы «Text View» вытягивался по ширине, при повороте экрана, но при этом не более чем на 300 пикселей. Для этого нам необходимо добавить еще одну связь. В менеджере файлов проекта, выбираем файл ViewController.xib, затем выбираем «Text View» и добавляем связь «Width». Связь можно добавить кликнув по кнопке «Pin» на мини панели «AutoLayout» расположенную в правом нижнем углу редактора интерфейса

или через меню «Editor -> Pin -> Width». После создания связи зададим свойства как показано на следующем рисунке:

Мы создали связь с максимальным приоритетом (1000), ширина которой должна быть меньше или эквивалентна 300 px.

Все бы хорошо, но у нас возникла логическая проблема - конфликт связей. У «Text View» две конкурирующих связи: первая - закрепляет правую сторону «Text View»; вторая, которую мы только что создали - задает максимальную ширину. При повороте экрана, система не может одновременно удовлетворить требования обеих связей, если сейчас мы запустим пример в симуляторе и перевернем экран устройства в портретную ориентацию, то результат не будет отличатся от приведенного выше.

Первое решение, которое сразу же напрашивается - удалить первую связь, которая закрепляет правую сторону «Text View», но делать этого не стоит. Эта связь нужна, так как правая сторона «Text View» должна быть прикреплена к правой стороне экрана, пока ширина экрана не превышает 300 px. Решение заключается в использовании приоритетов связей.

Каждой связи может быть назначен приоритет, значение которого находиться в диапазоне от 0 до 1000. В нашем случае мы должны задать более высокий приоритет у связи которая задает ширину «Text View», тогда при повороте экрана будет применена именно эта связь.

Выделите «Text View», затем в инспекторе размеров (Size Inspector) выберите связь «Trailing Space to: Superview» и в свойствах установите приоритет в значение 900.

Соберем и запустим проект в симуляторе:

Теперь при повороте экрана устройства «Text View» растягивается только до своего максимального значения в 300 px.

Поиграемся еще немного с AutoLayout. Удалим все ранее добавленные элементы с экрана. И добавим 3 кнопки в самый низ, как показано на рисунке:

Interface Builder создал следующие связи:

Запустим симулятор и посмотрим как выглядит интерфейс в портретной ориентации

Отлично! Теперь посмотрим в ландшафтной ориентации

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

Выбираем среднюю кнопку и добавляем связь «Width»

и установим такие свойства:

Relation: Equal
Constant: 73
Priority: 1000

C зажатой клавишей ⌘cmd выделяем левую и центральную кнопки и добавляем связь «Horizontal Spacing»

и зададим свойства:

Relation: Equal
Constant: Standart
Direction: Leading to Trailing
Priority: 1000

Повторим пункт 2 для правой и средней кнопки.

Теперь при запуске в портретной ориентации центральная кнопка будет иметь фиксированное значение, а крайние кнопки будут тянутся.

Можно задать связи, чтобы все кнопки меняли свой размер одинаково: 

Для того, чтобы добиться такого поведения необходимо:

1. Добавляем на экран три кнопки:

Левая кнопка должна быть прикреплена к левому краю экрана, правая кнопка - к правому краю.

2. Выделяем все кнопки и добавляем связь «Widths Equally». Данная связь говорит о том, что кнопки должны иметь одинаковую ширину:

3. Выделяем правую и центральную кнопки и добавляем между ними промежуток:

со свойствами:

Relation: Less Than or Equal
Constant: 30
Direction: Leading to Trailing
Priority: 1000

4. Повторяем пункт 3 для левой и центральной кнопки

Anton Dobkin
Author

Anton Dobkin

Comments