Определите свои собственные макеты

Всякий раз, когда я использую раскадровку или файл XIB для создания собственного макета ячеек UICollectionViewили UITableView, я всегда задаюсь вопросом, не было бы здорово, если бы я мог использовать SwiftUI для определения макета? В этом году на WWDC (2022) Apple наконец-то сделала это.

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

В конце этой статьи вы узнаете:

  1. Как использовать UIHostingConfiguration
  2. Как настроить высоту ячейки
  3. Как отрегулировать вкладыш разделителя
  4. Как настроить поля макета ячейки

Здесь можно затронуть много тем, так что давайте приступим к делу.

Готовиться

Перед тем, как углубиться в основную тему, нам нужно сделать несколько вещей. Сначала импортируйте модуль SwiftUI в класс вашего контроллера представления.

import SwiftUI

После этого определите следующие типы данных, которые будут действовать как модель данных нашего списка:

Затем настройте представление коллекции, чтобы использовать конфигурацию макета списка.

Обратите внимание, что в приведенном выше коде мы не используем diffable источник данных. Диффузионный источник данных не является обязательным при создании пользовательской ячейки с помощью SwiftUI. Кроме того, поскольку список, который мы создаем, показывает статический набор данных, использование традиционного источника данных намного проще и понятнее.

Наконец, давайте реализуем необходимые UICollectionViewDataSource методы:

Обратите внимание на swiftUICellRegistration, использованный в приведенном выше коде, мы скоро займемся этим. На данный момент просто имейте в виду, что с помощью swiftUICellRegistration мы связываем нашу пользовательскую ячейку SwiftUI с представлением коллекции.

Со всем этим мы можем теперь перейти к забавным вещам.

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

До iOS 16, чтобы создать собственный UICollectionViewListCell, нам нужно было создать подкласс UICollectionViewListCell и определить собственный объект конфигурации, который соответствует протоколу UIContentConfiguration, что несколько хлопотно.

С введением UIHostingConfiguration в iOS 16 теперь можно определять макет и содержимое пользовательской ячейки с помощью SwiftUI, устраняя необходимость в создании подкласса UICollectionViewListCell и пользовательского объекта конфигурации.

Согласно документации Apple, структура UIHostingConfiguration соответствует протоколу UIContentConfiguration. Поэтому мы можем использовать его во время регистрации ячейки следующим образом:

Из приведенного выше кода есть две вещи, о которых вам нужно знать.

Во-первых, тип ячейки, который мы используем для регистрации ячейки, — UICollectionViewListCell (не UICollectionViewCell). Поскольку мы создаем список, использование UICollectionViewListCell даст нам некоторые из его полезных функций, таких как:

  1. Возможность отображения сотовой фурнитуры
  2. Возможность регулировки вставки разделителя (об этом позже)
  3. Различные виды ячеек (в зависимости от конфигурации макета представления коллекции)

Во-вторых, обратите внимание, что мы определяем регистрацию ячейки как переменную экземпляра (swiftUICellRegistration). Как вы видели ранее, это позволяет нам использовать swiftUICellRegistration в методе источника данных представления коллекции.

Хорошо, достаточно сказано. Давайте определим макет и содержимое ячейки с помощью SwiftUI, чтобы увидеть все в действии.

На этом этапе, если вы попытаетесь запустить пример кода, вы увидите, что заполняются следующие ячейки.

Внесение корректировок

Регулировка высоты ячейки

На изображении выше вы должны заметить, что наша текущая высота ячейки немного меньше, чем мы ожидаем. Как упоминалось в одной из моих предыдущих статей, UICollectionViewListCell — это ячейка с автоматическим размером. Это означает, что он будет автоматически регулировать свой размер в зависимости от макета и содержимого.

Имея это в виду, мы можем легко увеличить высоту ячейки, просто увеличив высоту HStack.

Примечание. Обязательно установите рамку HStack перед установкой желтого фона, иначе высота желтого фона не увеличится соответствующим образом.

Вот конечный результат:

Регулировка вкладыша разделителя

В настоящее время передний край разделителя выровнен с текстом в ячейке. Это поведение по умолчанию, унаследованное от UICollectionViewListCell. К сожалению, это не то, чего мы хотим.

Чтобы добиться того, чего мы хотим, мы можем использовать модификатор alignmentGuide следующим образом:

Приведенный выше код выравнивал передний край разделителя с передним краем HStack и выравнивал задний край разделителя с задним краем HStack. Вот что мы получим:

Настройка полей макета ячейки

По умолчанию содержимое SwiftUI ячейки вставляется от краев ячейки на основе полей макета ячейки в UIKit. Чтобы перезаписать поле по умолчанию, мы можем использовать модификатор UIHostingConfiguration margins для этого.

При этом наша пользовательская ячейка достигла своей окончательной формы.

Теперь, когда мы закончили создание нашей пользовательской ячейки с помощью SwiftUI, мы можем выполнить простой рефакторинг, создав выделенное представление SwiftUI для нашего пользовательского макета ячейки.

Имея это на месте, теперь мы можем создать UIHostingConfiguration следующим образом:

Обратите внимание, как мы настраиваем содержимое MyFirstSwiftUICell, передавая объект item во время инициализации.

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

Подведение итогов

Пример, который я использую в этой статье, в основном сосредоточен на создании пользовательского UICollectionViewListCell, но это не значит, что вы не можете использовать UIHostingConfiguration для создания пользовательского UICollectionViewCell. Фактически, согласно Apple, UIHostingConfiguration предназначен для работы как с UICollectionViewCell, так и с UITableViewCell.

Однако обратите внимание, что UIHostingConfiguration доступно только в iOS 16 и выше. Если вашему приложению по-прежнему необходимо поддерживать версию iOS ниже, чем iOS 16, вы можете подумать о том, чтобы вернуться к способу, отличному от SwiftUI.

И последнее, но не менее важное: вот полный пример кода.

Спасибо за прочтение.

Want to Connect?
Reach me out on Twitter if you have any questions.