Connect with us

Разработка

Темы в современных iOS-приложениях с UITraitCollection

Эта статья представляет собой законченное описание того, как добавить тематическое оформление в реальное приложение.

Опубликовано

/

     
     

Совсем недавно (с iOS 17) Apple представила довольно удобный способ обработки смены тем в приложениях для iOS. Раньше это было довольно мучительно (об этом рассказывается в нескольких хорошо написанных статьях в блогах Кристиана Селига и Shadowfacts).

С появлением UITraitAppearance все стало проще.

Эта статья представляет собой законченное описание того, как добавить тематическое оформление в реальное приложение. Я также включу пример кода для реального проекта, который вы можете скачать (или вы можете просто скачать его на GitHub прямо сейчас, если вы просто хотите погрузиться в работу).

Предварительные условия

Прежде чем использовать этот подход, необходимо помнить о двух вещах.

  • Ваше приложение должно быть нацелено на iOS 17 или более новую версию.
  • Вы должны использовать делегат сцены.

Поэтому, прежде чем продолжить, убедитесь, что все в порядке. В противном случае все не будет работать!

Теперь, когда мы разобрались с этим, давайте приступим.

Понимание коллекций трейтов

Коллекции трейтов — не совсем новинка в iOS; они появились еще в iOS 8. Так что если вы опытный iOS-разработчик, вы, вероятно, уже сталкивались с этим API.

Но для тех, кто еще не знаком с ним, вот как в документации UIKit определяется коллекция трейтов:

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

Круто. Давайте читать дальше.

Свойство traitCollection протокола UITraitEnvironment содержит характеристики (трейты), которые описывают состояние различных элементов пользовательского интерфейса iOS, таких как класс размера, масштаб отображения и направление компоновки. Вместе эти трейты составляют среду трейтов UIKit (trait environment).

Теперь стало немного понятнее. UITraitCollection представляет данные о том, как должны выглядеть и вести себя объекты, основанные на особенностях самого устройства и предпочтениях пользователя (хороший пример — темный режим).

Темы в современных iOS-приложениях с UITraitCollection

Одна из проблем с UITraitCollection заключается в том, что трейты неизменяемы. Как мы можем позволить пользователям менять темы, если это так? Здесь на помощь приходит протокол UIMutableTraits (это одно из ключевых изменений в iOS 17, которое помогает сделать это возможным).

Вот что говорит Apple:

Протокол UIMutableTraits предоставляет доступ на чтение и запись для получения и установки значений трейтов в базовом контейнере. UIKit использует этот протокол для облегчения работы с экземплярами UITraitCollection, которые являются неизменяемыми и доступны только для чтения. Инициализатор UITraitCollection init(mutations:) использует экземпляр UIMutableTraits, что позволяет установить пакет значений характеристик за один вызов метода. UITraitOverrides соответствует UIMutableTraits, что позволяет легко переопределять трейты в таких средах, как представления и контроллеры представлений.

Немного жаргона, но это означает, что UIMutableTraits позволяет нам манипулировать трейтами по требованию (кажется полезным 🤔).

Все, что нам нужно сделать, это привести наш трейт в соответствие с UITraitDefinition, а затем добавить геттеры и сеттеры в расширение UIMutableTraits.

Определяем вашу тему

У нас есть все необходимые компоненты, но как их использовать?

Давайте начнем с очень простой темы, у которой есть только два варианта (светлый и темный) и два свойства (цвет переднего плана и фона).

Мы воспользуемся динамическим инициализатором UIColor (init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)) для определения наших цветов. Из документации:

Используйте этот метод для создания цветового объекта, значения компонентов которого меняются в зависимости от активного в данный момент трейта. Блок, который вы предоставляете, создает новый цветовой объект на основе трейтов в предоставленной коллекции трейтов.

Идеально. Как раз то, что нам нужно.

Теперь создайте определение трейта.

Все трейты, содержащиеся в коллекции UITraitCollection, соответствуют этому протоколу. Вы можете создавать собственные трейты, определяя свой собственный соответствующий тип.

Наконец, расширим UITraitCollection и добавим тему в UIMutableTraits.

Использование темы

Теперь, когда у нас есть тема, мы можем динамически применять значения темы к элементам пользовательского интерфейса. Это очень просто:

Но подождите, вы могли заметить, что мы кое-что упустили: тема по умолчанию явно будет работать, но как нам ее изменить? Для этого нам нужно использовать переопределения трейта.

Переопределения трейтов

Переопределение трейта — это способ изменить изменяемый трейт в коллекции трейтов (это та штука, которая была недавно представлена в iOS 17 и которая делает все это возможным). Вы, вероятно, захотите делать это при запуске приложения и при обновлении темы.

Чтобы обработать переопределение трейта при запуске приложения, его нужно будет включить в метод scene(_:willConnectTo:options:) в делегате сцены (еще одно напоминание: подход, который мы используем, требует наличия сцен).

Вот как может выглядеть полная реализация делегата сцены:

А вот соответствующая конфигурация, которая хранит тему. Возможно, у вас уже есть существующий метод сохранения настроек по умолчанию, поэтому не используйте этот код; это просто иллюстрация.

И наконец, вот как динамически изменить тему. Это можно сделать в любом месте, где есть доступ к windowScene, например в UIViewController:

Заключение

Я только слегка прошелся по возможностям тематического оформления с помощью UITraitCollection API (черт, я даже не упомянул SwiftUI!). Но этого должно быть достаточно, чтобы начать.

Посмотрите пример приложения iOSTraitCollectionThemingExample на GitHub, демонстрирующий эту технику в действии.

Если вы хотите продолжить, вот несколько других ресурсов, которые я рекомендую:

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: