UICollectionViewCompositionalLayout이란?
compositionalLayout은 collectionView layout의 한 종류입니당
각각의 작은 구성들이 모여서 전체 레이아웃을 구성하는 방식으로,
기존의 컬렉션뷰 레이아웃 구현에 비해 좀 더 다양한 구성의 레이아웃을 구현할 수 있습니다.
section + group + item 별로 묶어서 레이아웃을 구성하기 때문에
section 별로 다른 레이아웃을 구성하기가 쉽다는 점이 장점입니다.
가장 작은 단위의 item부터 item을 묶어둔 group,
그 group을 묶는 section 으로 구성되어 있습니다.
item, group의 각 사이즈를 만들어주고
item은 group의 요소로, group은 section의 요소로 넣어줍니다
NSCollectionLayoutDimension
item, group, section의 사이즈를 정해주는 객체
absolute
고정된 크기 값
estimated
초기값을 설정해주면 런타임 후 item 사이즈에 따라 변경
fractionalWidth · fractionalHeight
뷰에 대한 가로·세로 비율로 결정
ex) fractionalWidth(1.0) → 뷰 가로 길이의 1.0 값
fractionalHeight(1/3) → 뷰 세로 길이의 1/3 값
구현을 해볼게욜
인스타그램 검색 뷰 클론코딩을 하면서 compositional layout을 사용해보게 되었어욜
func compositionalLayout() -> UICollectionViewLayout {
// 1. item
let squareSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1/3),
heightDimension: .fractionalWidth(1/3))
let squareItem = NSCollectionLayoutItem(layoutSize: squareSize)
squareItem.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 1, bottom: 1, trailing: 1)
// 2. group
let squareGroupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1/3))
let squareGroup = NSCollectionLayoutGroup.horizontal (
layoutSize: squareGroupSize,
subitem: squareItem,
count: 3)
// 3. section
let section = NSCollectionLayoutSection(group: squareGroup)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
section별로 다른 레이아웃 구현
홀수 섹션은 오른쪽에 세로로 긴 이미지를, 짝수 섹션은 왼쪽에 세로로 긴 이미지를 배치한 레이아웃을 구현해봤습니다.
func compositionalLayout() -> UICollectionViewCompositionalLayout {
UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
// 1. item
let squareSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1/3))
let largeSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(2/3))
let squareItem = NSCollectionLayoutItem(layoutSize: squareSize)
let largeItem = NSCollectionLayoutItem(layoutSize: largeSize)
squareItem.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 1, bottom: 1, trailing: 1)
largeItem.contentInsets = NSDirectionalEdgeInsets(top: 1, leading: 1, bottom: 1, trailing: 1)
// 2. group
let squareGroupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1/3),
heightDimension: .fractionalWidth(2/3))
let squareGroup = NSCollectionLayoutGroup.vertical (
layoutSize: squareGroupSize,
subitem: squareItem,
count: 2)
let largeGroupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1/3),
heightDimension: .fractionalWidth(2/3))
let largeGroup = NSCollectionLayoutGroup.vertical (
layoutSize: largeGroupSize,
subitem: largeItem,
count: 1)
// 2-1. group 안에 group
let totalGroupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(2/3))
// 3. section에 따라 group 구성 다르게
switch section % 2 {
case 0:
let totalGroup = NSCollectionLayoutGroup.horizontal (
layoutSize: totalGroupSize,
subitems: [squareGroup, squareGroup, largeGroup])
let section = NSCollectionLayoutSection(group: totalGroup)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
return section
default:
let totalGroup = NSCollectionLayoutGroup.horizontal (
layoutSize: totalGroupSize,
subitems: [largeGroup, squareGroup, squareGroup])
// 3. section
let section = NSCollectionLayoutSection(group: totalGroup)
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
return section
}
}
}
참고자료
'iOS' 카테고리의 다른 글
[iOS] 푸시알림 받아서 처리하기 (0) | 2022.10.12 |
---|---|
[iOS] 컴포넌트를 코드베이스, 스토리보드에서 둘다 쓸 수 있도록 하는 방법🐯 (1) | 2022.05.30 |
[iOS] RxDataSource 😡 (0) | 2022.05.17 |
[iOS] Haptic 사용법👋 (0) | 2022.04.23 |
[iOS] Diffable Datasource❓ (0) | 2022.03.18 |