Статьи

Использование UIStackView с MarkupKit

В 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.