В iOS 9 компания Apple представила новое средство реализации автоматического управления макетом (или «авторазметкой») в приложениях iOS: класс UIStackView . Этот UIView
подкласс размещает свои подпредставления либо по горизонтали, либо по вертикали, при необходимости изменяя их размеры или перераспределяя их по мере необходимости в ответ на изменение размера устройства или ориентации.
В более ранних версиях iOS макет представления должен был выполняться либо вручную, либо с помощью ограничений макета, ни один из которых не был особенно удобен. UIStackView
значительно упрощает этот процесс. Внутренне он использует ограничения макета для управления размером и положением представлений, скрывая детали управления ограничениями и освобождая разработчиков от ответственности за непосредственную работу с ними.
В последней версии MarkupKit добавлена поддержка создания и настройки UIStackView
экземпляров в разметке. Например, следующий документ создает вертикальный вид стека, содержащий три метки:
<UIStackView axis="vertical" alignment="center" spacing="8">
<UILabel text="One"/>
<UILabel text="Two"/>
<UILabel text="Three"/>
<UIView/>
</UIStackView>
Метки будут горизонтально центрированы в представлении стека и будут разделены 8 пикселями вертикального пространства. Пустой конечный UIView
экземпляр используется для создания гибкого отступа между финалом UILabel
и нижней частью представления контейнера, обеспечивая закрепление содержимого представления стека в верхней части представления.
Эта разметка производит следующий вывод на iPhone 6 под управлением iOS 9:
Виды стека могут быть вложенными для создания более сложных макетов. Например, следующая разметка создает представление вертикального стека, содержащее два представления горизонтального стека. Они, в свою очередь, содержат три метки и три изображения соответственно. Пустые представления также используются в этом примере для создания гибкого отступа:
<UIStackView axis="vertical" spacing="8">
<UIStackView axis="horizontal" spacing="8" layoutMargins="12" layoutMarginsRelativeArrangement="true">
<UILabel text="One"/>
<UILabel text="Two"/>
<UILabel text="Three"/>
<UIView/>
</UIStackView>
<UIStackView axis="horizontal" spacing="8" layoutMargins="12" layoutMarginsRelativeArrangement="true">
<UIImageView image="vw.png"/>
<UIImageView image="mini.png"/>
<UIImageView image="chevy.png"/>
<UIView/>
</UIStackView>
<UIView/>
</UIStackView>
Атрибут layoutMargins используется для создания 12-пиксельного зазора вокруг содержимого горизонтальных стеков. Поскольку представления стека по умолчанию настроены на игнорирование полей макета, свойство layoutMarginsRelativeArrangement установлено так, чтобы указывать представления true
стека для соблюдения указанного поля.
Эта разметка производит следующий вывод:
Несмотря на то, что эти примеры несколько тривиальны, они предлагают эффективную демонстрацию UIStackView
потенциала России. Многие распространенные сценарии компоновки могут быть реализованы просто путем применения различных комбинаций вложенных представлений стека.
Конечно, подобное поведение макета может быть достигнуто с помощью существующих LMRowView
и LMColumnView
классов MarkupKit . Мол UIStackView
, эти классы используют ограничения макета внутри, скрывая часто неловкие детали управления ограничениями от разработчиков. Следующая разметка с использованием представлений строк и столбцов создает выходные данные, идентичные предыдущему примеру на основе представления стека:
<LMColumnView>
<LMRowView layoutMargins="12">
<UILabel text="One"/>
<UILabel text="Two"/>
<UILabel text="Three"/>
<LMSpacer/>
</LMRowView>
<LMRowView layoutMargins="12">
<UIImageView image="vw.png"/>
<UIImageView image="mini.png"/>
<UIImageView image="chevy.png"/>
<LMSpacer/>
</LMRowView>
<LMSpacer/>
</LMColumnView>
Обратите внимание, что, так как LMRowView
и LMColumnView
настроены для соблюдения полей макета по умолчанию, нет необходимости устанавливать свойство layoutMarginsRelativeArrangement. Виды строк и столбцов также имеют значение интервала по умолчанию, равное 8 пикселям, поэтому явная установка свойства «интервал» также не требуется.
Также обратите внимание, что в этом примере LMSpacer
экземпляры используются для создания гибкого пространства между конечными видами и краем родительского контейнера. LMSpacer
это чрезвычайно простой UIView
подкласс, единственной целью которого является обеспечение такого расстояния. Он переопределяет UIView
«s hitTest:withEvent:
метод , чтобы вернуться , nil
чтобы гарантировать , что это не мешает события прикосновения от достижения , лежащие в основе взглядов. LMSpacer
также может быть использован с UIStackView
.
Представления макета MarkupKit также предлагают некоторые дополнительные функции, не предоставляемые UIStackView
. Например, поскольку это «подкласс отсутствия рендеринга» UIView
, UIStackView
он не позволяет вызывающей стороне устанавливать цвет фона. Тем не менее, цвета фона поддерживаются LMRowView
и LMColumnView
. Это важное соображение при создании пользовательских контроллеров представления. Поскольку у UIStackView
цвета не может быть цвета фона, перемещение контроллера на основе стека в UINavigationController
может вызвать некоторые проблемы рендеринга:
Контроллер на основе представления строк или столбцов с цветом фона плавно анимируется:
Кроме того, LMRowView
и LMColumnView
предоставить возможность распределять подпредставления по весу, что в настоящее время кажется невозможным UIStackView
. Распределение на основе веса позволяет вызывающей стороне точно указать, какой процент доступного пространства в контейнере должен быть выделен для конкретного подпредставления.
Например, следующая разметка создает представление столбца, содержащее два представления строки. Первому виду строки присваивается вес 1, а второму — вес 2, в сумме 3. В результате первая строка получит 1/3 или около 33% доступного пространства в столбце, а вторая строка будет иметь 2/3, или около 66% доступного пространства:
<LMColumnView>
<LMRowView weight="1" backgroundColor="#ffcccc">
<LMSpacer/>
<UILabel text="One"/>
<UILabel text="Two"/>
<UILabel text="Three"/>
<LMSpacer/>
</LMRowView>
<LMRowView weight="2" backgroundColor="#ccffcc">
<LMSpacer/>
<UILabel text="Four"/>
<UILabel text="Five"/>
<UILabel text="Six"/>
<LMSpacer/>
</LMRowView>
</LMColumnView>
Вывод этой разметки при запуске в режиме portait выглядит следующим образом:
В ландшафте это выглядит так:
Наконец, UIStackView
требуется устройство под управлением iOS 9 или более поздней версии. UIRowView
и UIColumnView
поддерживаются на iOS 8 и выше.
С другой стороны, UIStackView
предоставляет некоторые возможности, которые не поддерживаются LMRowView
или LMColumnView
. Например, он предлагает несколько дополнительных параметров распространения, а также возможность анимировать изменения своего содержимого и свойств. См. UIStackView
Документацию класса для получения дополнительной информации об этих функциях.
Итак, когда вы должны использовать один или другой? Оба типа представлений могут использоваться в одном приложении, а также в одной иерархии представлений. Если вам нужна возможность указать цвет фона для вашего контейнера, вы хотите распределить подпредставления по весу или вам нужна поддержка iOS 8, используйте представление в виде строки или столбца. Если вам нужно анимировать изменения макета или распространять подпредставления другими способами и вы ориентируетесь исключительно на iOS 9, используйте стековое представление.
Комбинируя возможности UIStackView
с возможностями LMRowView
и LMColumnView
, вы можете быстро и легко создавать сложные пользовательские интерфейсы, которые будут автоматически адаптироваться к изменениям размера и ориентации, предоставляя гораздо более отзывчивый и привлекательный интерфейс для ваших пользователей.
Для получения дополнительной информации см. « Представление MarkupKit » или посетите проект MarkupKit на GitHub.