Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Compositional Layout?
Compositional Layout — это современный, декларативный и гибкий API, представленный Apple в iOS 13 (в рамках фреймворка UIKit) для построения сложных и адаптивных макетов в коллекциях (UICollectionView). Он пришёл на смену старому, более императивному и монолитному UICollectionViewFlowLayout, предлагая модульный подход к компоновке интерфейса. Основная философия заключается в "композиции" (отсюда и название) — сборке сложного макета из небольших, независимых и многократно используемых компонентов.
Ключевые компоненты Compositional Layout
Структура строится на трёх основных "кирпичиках", которые вкладываются друг в друга по иерархии:
-
NSCollectionLayoutItem (Элемент) — это фундаментальная единица, представляющая самую маленькую отрисовываемую часть, обычно ячейку (cell). Элемент определяет свой размер.
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)) let item = NSCollectionLayoutItem(layoutSize: itemSize) -
NSCollectionLayoutGroup (Группа) — контейнер, который объединяет один или несколько
NSCollectionLayoutItem(или даже другие группы) и определяет, как они располагаются относительно друг друга — горизонтально, вертикально или в пользовательской конфигурации. Группа управляет внутренним расположением элементов.// Горизонтальная группа из 3 элементов let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(44)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 3) -
NSCollectionLayoutSection (Секция) — контейнер верхнего уровня, который объединяет одну или несколько
NSCollectionLayoutGroup. Секция определяет поведение всего блока интерфейса: интервалы (interGroupSpacing), заголовки и футеры, отступы (contentInsets), а также возможность прикрепления заголовка (orthogonalScrollingBehavior).let section = NSCollectionLayoutSection(group: group) section.interGroupSpacing =間隔10 section.orthogonalScrollingBehavior = .continuous // Для горизонтального скролла внутри секции
Итоговый макет создаётся композицией этих частей в объект UICollectionViewCompositionalLayout.
let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
// Здесь, на основе номера секции или окружения, можно возвращать разные макеты
return createCustomSection(for: sectionIndex)
}
collectionView.setCollectionViewLayout(layout, animated: false)
Преимущества перед UICollectionViewFlowLayout
- Модульность и переиспользование: Вы можете создать библиотеку независимых компонентов-макетов (секций) и комбинировать их как "Лего".
- Ортогональная прокрутка (Orthogonal Scrolling): Реализация горизонтально скроллящих секций внутри вертикальной коллекции становится тривиальной задачей (см. свойство
.orthogonalScrollingBehaviorвыше). Это главная "фишка" для создания интерфейсов, подобных App Store. - Декларативность: Код для описания макета более читаем и сосредоточен на что должно быть, а не на как это вычислять.
- Адаптивность (Adaptive Layouts): Используя
NSCollectionLayoutEnvironment, можно легко создавать разные макеты для различных размеров класса (compact,regular), учитывая ориентацию устройства или размер контейнера (например, iPad vs iPhone, split-view). - Поддержка заголовков/футеров на уровне секций и глобальных (Boundary Supplementary Items): Более мощная и гибкая система, чем раньше.
- Вложенность групп (Nested Groups): Позволяет создавать невероятно сложные сетки и иерархические структуры.
Практический пример: Сетка с ортогональным скроллом
Типичный сценарий — главный экран приложения с вертикальным скроллом, где одна секция — это сетка 3x2, а следующая — горизонтально скроллящийся ряд.
func createLayout() -> UICollectionViewLayout {
return UICollectionViewCompositionalLayout { (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
switch sectionIndex {
case 0:
// Секция 0: Сетка 3x2
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1/3 * 0.75)) // Сохраняем пропорции
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
return section
case 1:
// Секция 1: Горизонтальный скроллинг
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(160),
heightDimension: .absolute(220))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous // Включаем горизонтальный скролл!
section.interGroupSpacing = 10
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 16, bottom: — отступ30, trailing: 16)
return section
default:
return nil
}
}
}
Итог: Compositional Layout — это мощный инструмент, который кардинально упростил создание современных, сложных и отзывчивых интерфейсов в iOS. Его изучение и внедрение является практически обязательным для любого iOS-разработчика, работающего с коллекциями, так как он стал стандартом де-факто в экосистеме UIKit.