Auto Layout занимается динамическим вычислением позиции и размера всех view в view иерархии, на основе constraints — правил заданных для того или иного view. Самый большой и очевидный плюс для разработчика в использовании Auto Layout в том, что исчезает необходимость в подгонке размеров приложения под определенные устройства — Auto Layout делает это за вас, динамически изменяя интерфейс в зависимости от внешних или внутренних изменений.

Примером внешних изменений может быть: Изменение размера окна в macOS, изменение ориентации экрана, различные размеры экранов.

Пример внутренних изменений: Изменение контента в окне, изменения в зависимости от языка и т.д.

Создать свой интерфейс можно 3-мя способами: программно, на основе маски, которая автоматически подстраивается под изменения или использовать Auto Layout.

Отличие Auto Layout от других способов в том, что вам больше не нужно писать код, который изменяет интерфейс в зависимости от размера окна и других элементов, вместо этого Auto Layout самостоятельно вычисляет расположение элемента интерфейса в приложении и изменяет его относительно окружения.

Auto Layout без ограничений


Если вы по каким-либо причинам не хотите использовать правила(constraints) или ваш интерфейс содержит в себе множество элементов расположение которых можно изменять бесконечно, вам на помощь придет Stack View.

Stack View — это ваша палочка выручалочка при создании комплексных интерфейсов. Он может расставлять элементы внутри себя с данными параметрами:

axis (только UIStackView) — определяет ориентацию, горизонтально или вертикально;
orientation (только NSStackView) — тоже что и axis у UIStackView;
distribution — определяет расположение элементов в данной ориентации;
alignment — определяет расположение элементов перпендикулярно ориентации StackView;
spacing — определяет расстояние между соседними элементами;

Для получения максимально удовлетворительных результатов вы можете использовать constraints в самом StackView либо вкладывать несколько StackView в StackView и затем использовать constraints например для выравнивания по центру экрана.

Анатомия Constraint


Вся суть правил сводится к созданию вычисления у которого может быть только один ответ — расположение элемента интерфейса.

Выглядит это приблизительно так:

Кнопка.Верх = ВысшаяТочкаИнтерфейса.Низ + 100

По данному выражению понятно что оно означает и какое правило устанавливает для view. Как уже было сказано, вычисления Auto Layout всегда происходят относительно ближайших элементов, будь это граница экрана или соседняя кнопка.

В своих вычислениях constraints используют множители, ближайшие объекты и константы вроде + 100 из примера выше. Так же при создании правил не обязательно, чтобы это были равенства, вы можете использовать >= или<=.

При создании layout желательно указывать два правила для каждого измерения на элемент. Но не забывайте про StackView, который вам очень поможет при создании интерфейса.

Самым интересным фактом является то, что при создании constraints вы можете устанавливать приоритетность самих constraints. При вычислении, Auto Layout старается удовлетворить все constraint'ы в порядке приоритетности. Приоритет = 1000 — обязателен. Все остальные, менее приоритетные правила вы можете устанавливать для придания четкости обработке расположения элементов вашего интерфейса. В случае, если один из constraint'ов будет не правильно вычислен, Auto Layout использует ближайший constraint и начнет отталкиваться от него. Тем не менее, настоятельно рекомендую не перегружать интерфейс различными правилами и использовать дополнения только для достижения нужного результата.

Создание Auto Layout и его составляющих


Вы можете создавать constraint'ы 3-мя способами:

1. CTRL + Перетаскивание, например, от label к верхней границе.
2. Используя Stack, Align, Pin и Resolve Tools.
3. Предоставить Interface Builder построить constraints вместо вас.

Среди данных пунктов самый важный именно 2-й, так как использование этой панели является основным инструментом при создании разметки.

Stack — собственно та самая кнопка, с помощью которой вы можете поместить выделенные детали интерфейса в StackView. Interface Builder сам решает каким будет StackView в зависимости от расположения элементов. Кроме кнопки Stack, StackView можно создать перетягиванием из библиотеки объектов, как любой другой элемент.

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

Pin — меню, позволяющее вам задать жесткие рамки относительно своего размера или ближайшего предмета. В нем вы выбираете какой constraint вы хотите задать в том или ином направлении и установить его параметры. Также с помощью данного меню можно, к примеру, придать группе кнопок одинаковый размер, не изменяющийся не смотря на масштаб экрана.

Resolve Tools — самый лучший помощник в отладке constraint'ов. Основные возможности этого меню: убрать все правила, добавить предположительные constraints(Interface Builder построит все правила за вас), добавить отсутствующие constraints, обновить constraints или frames(положение объектов).
Как вы видите, тут довольно много важных пунктов и они призваны облегчить все тяготы разработчика.

Редактировать constraint'ы можно нажав на них в Interface Builder, найти в Size Inspector или в списке Document Outline. При редактировании параметров вы можете задавать идентификаторы для более легкого понимания и нахождения их в логах и консоли при выполнении различных отладок.

Немаловажным аспектом при установке правил для элементов, являются параметры CHCR (Content-Hugging and Compression-Resistance Priorities) — эти параметры влияют на изменение самого элемента в зависимости от вышестоящего view. Грубо говоря Hugging — это нежелание элемента увеличиваться, а Compression-Resistance — нежелание уменьшаться. С помощью параметров CHCR можно к примеру изменять соотношение сжатия-расширения элементов в StackView в зависимости от размеров находящихся в нем элементов.

Будьте внимательны — macOS и iOS рассчитывают layout'ы по разному: В macOS, Auto Layout может изменять размер окна и размер содержимого, а в iOS он может менять только размер содержимого, так как система сама определяет размер и границы приложения.

При написании статьи я основывался на материалах официального гайда по Auto Layout
Поделиться с друзьями
-->

Комментарии (7)


  1. klirichek
    17.10.2016 10:03

    Очень странно видеть статью про интерфейс, в которой НИ ОДНОЙ иллюстрации.


    1. Engylizium
      17.10.2016 11:29
      +1

      Извините, я конечно же знал на что шел когда писал статью. Я сделал упор на то что все люди работающие с Interface Builder уже знают где и что находится. Статья больше представляет собой теоретический гайд по Auto Layout и больше предназначен для устранения множества вопросов у изучающих, которые уже знают что и где, но не знают как этим правильно пользоваться.


  1. neatek
    17.10.2016 11:16

    Я вот столкнулся с проблемой, что TableView не могу разместить в ScrollView. Еще не до конца понимаю всю систему) Говорит что ambiguous height, почему TableView не может быть растянут на содержимое, scrollable отключал. Читать и еще раз читать надо, и любой материал по сути своей полезен.


    1. Engylizium
      17.10.2016 11:21

      Я только что попробовал установить TableView в ScrollView как вы сказали, у меня вполне получилось. Я просто расположил TableView по центру ScrollView и через меню Resolve Tools -> Add Missing Constraints для всех Views и все нормально вписалось. Может быть вы хотите как-то по другому? Если мой комментарий вам помог, тогда советую посмотреть какие constraints вам нужно было установить для нормального отображения.


      1. neatek
        18.10.2016 15:20

        Add Missing Constraints как оказалось добавляет кучу не нужного мусора, причем фиксированного, что не подходит для разных размеров экрана. Но все же добавил TableView в ScrollView, переделав полностью весь View. Высота статичная у TableView и через Swift буду программно менять высоту относительно контента, который расположен внутри. Количество элементов в TableView маленькое, поэтому посмотрю как будет, до поиска других вариантов решения.


        1. Engylizium
          18.10.2016 15:41

          Add Missing Constraints в большинстве своем служит для того что бы разработчик увидел, каких ему может не хватать constraints или для простых вещей вроде центровки UILabel внутри UIView.
          Не забывайте, что вы можете сами задавать и менять constraints программно или через IB, к этому относится и прописывание соотношений или формул для подобных целей.
          И мне кажется, что динмическое изменение высоты через код, самый простой и удобный способ.
          Работа с Auto Layout по большей части креативная и требует экспериментов, после которых вы сможете создавать любые интерфейсы без особых проблем.


    1. rsi
      24.10.2016 13:17
      +1

      При размещении чего либо в ScrollView с использованием auto layout стоит понимать всего один нюанс. Это то что у ScrollView есть два размера — внешний (размер самого ScrollView) и внутренний (размер контента). Собственно нельзя растянуть что то внутри ScrollView по ширине (или высоте) потому что у ScrollView нет четких значений высоты и ширины, они зависят от элементов внутри. ambiguous height — как раз и значит что высота не может быть высчитана.

      Конкретно в вашем случае вы пытаетесь прировнять высоту таблицы к высоте контента ScrollView, а она в свою очередь считается по единственному элементу внутри — таблице и вы попадаете в рекурсию)