В iOS-разработке выравнивание контента и интервалы — это то, на что может уйти много времени. Давайте рассмотрим, как устанавливать ограничения с помощью UIKit, обновлять их и разрешать конфликты ограничений.
Ограничение(constraint) - это правило, позволяющее операционной системе размещать ваш компонент пользовательского интерфейса. В UIKit есть 2 основных способа установки ограничений: StoryBoard и кодом. В данной статье рассмотрим только подход кодом.
Создание нового ограничения
Первое, что нам нужно сделать, это отключить AutoresizingMask, который по умолчанию включён.
Активация
После создания нам нужно активировать наши ограничения. Для этого вы можете либо переключить ограничение на isActive, по одному, либо использовать.activate() функцию для одновременного обновления пакета ограничений.
Вы так же можете деактивировать их таким же образом.
Управление ограничениями
Ограничения можно обновлять после применения. Например, для изменения интервала или размера
Также можем анимировать view с помощью ограничений. Главное обязательно вызвать layoutIfNeeded()
Разрешение конфликтов ограничений
Теперь, когда мы изучили основы добавления, редактирования и активации ограничений, возникает проблема: разрешение конфликтующих ограничений.
В большинстве случаев Xcode укажет в консоли, что не может разрешить ограничения в консоли. При открытии Debug View Hierarchy мы можем проверить каждое ограничение и определить, откуда возникает конфликт.
Конфликты почти всегда возникают из-за приоритетных вопросов. Если я установлю для ограничения высоты значение, 100
а затем другое ограничение 50
, система не сможет сказать, какое из них применять.
Это создаст конфликт.
Чтобы обнаружить конфликт такого типа, мы можем установить Breakpoint с помощью UIViewAlertForUnsatisfiableConstraints для обнаружения неправильно настроенных ограничений
Как только мы определили, какие ограничения конфликтуют, мы можем изменить приоритет в пользу одного и уменьшить второе, максимальное значение которого равно 1000
Так же есть предопределенные значения, которые мы можем использовать повторно.
Intrinsic content size
Вы задавались иногда вопросом почему для Label можно не указывать размер, а для view обязательно? Сейчас мы рассмотрим почему это так происходит
Возьмём и разместим на экране View и Label.
При размещении view xcode выдаст ошибку и не отобразит нашу view
При размещении Label на экране спокойно отобразиться наш элемент при размещении Label на экране спокойно отобразиться наш элемент
Intrinsic content size - это размер контента у всех UI элементов (label, view, button и т. д.). Данное свойство определит какого размера должна быть view, чтобы разместить в ней контент. На табличке ниже мы можем рассмотреть Intrinsic content size для разных элементов UI
UIView и NSView - не имеют Intrinsic content size
Sliders - установлена только ширина, нужно задать высоту для слайдера
Labels, buttons, switches, и text fields - определена высота и ширина
Text views image views - Intrinsic content size может изменяться в зависимости от контента внутри (если не добавить контент, то тогда не будут определены размеры)
Auto Layout и Constraint Resistance
Для некоторых UIView мы не всегда можем применить конкретные значения. Например, если у нас есть UIButton с Tap
жестко заданным значением, при локализации текст может быть обрезан.
Чтобы справиться с этим, не требуя изменения приоритета, мы можем использовать другой набор функций, чтобы избежать такого поведения. Двумя из них являются Content Hugging и Content Resistance.
Content hugging priority - приоритет сопротивления превышения intrinsic content size (не хочу чтобы была больше)
Content compression resistance priority - приоритет сопротивления занижения intrinsic content size (не хочу чтобы была меньше)
Вернемся UIButton. Вместо того чтобы устанавливать ограничение ширины, чтобы избежать обрезки, можно применить сопротивление избежав сжатия. Другой текст локализации расширит его.
Safe area constraints
При поддержке нескольких устройств одной привязки может быть недостаточно. Например, если у вас есть status bar, navigation bar, как мы можем учитываем их размеры на разных устройствах?
К счастью, UIKit поставляется со свойством safeAreaLayoutGuide для адаптации safe area, чтобы мы могли сосредоточиться на view, а не на размеры расстояний между устройствами. Это позволяет нам иметь одинаковый интервал, например, для iPhone8 или iPhone13.
Пример c safeAreaLayoutGuide
Вывод
В заключение, Auto Layout — очень мощный API. Это определенно упростило разработку: применение дизайна на нескольких устройствах и изменение размера до нужного размера.
С ограничением безопасной зоны и различными приоритетами становится проще адаптировать к новым устройствам, от iPhone 13 mini до iPad Pro.
Поскольку мы можем очень быстро создать множество ограничений, может быть трудно отслеживать их все, когда возникает конфликт. К счастью, Xcode поставляется с различными инструментами для отслеживания этого.
Установка ограничений программным путем упрощает поддержку и отладку, поскольку в разработке участвует много человек и работать со storyboard в большой команде будет крайне сложно.