Search

CompositionalLayout를 사용해보자

 들어가며

DiffableDataSource, Snapshot를 사용해보자 에 이어서 이번엔 UICollectionViewCompositionalLayout를 사용해보려고 합니다.
전체 코드를 보면서 포스팅 내용을 함께 보고 싶으시다면, 해당 링크를 참고해주시면 됩니다.

 UICollectionViewCompositionalLayout

A layout object that lets you combine items in highly adaptive and flexible visual arrangements. 유연하고 적응력 뛰어난 시각적 정렬로 아이템을 결합할 수 있는 Layout 개체
Compositional Layout은 CollectionViewLayout의 한 유형 중에 하나 입니다.
Compositional은 설명처럼 유연합니다. 유연할 수 있는 이유는 Compositional이 가지고 있는 작은 구성 요소들 덕분입니다. 작은 구성 요소들은 item, group, section 입니다.
세 가지 구성 요소를 전체 Layout으로 결합하거나 구성함으로써 Compositional은 모든 종류의 정렬을 구축할 수 있도록 도와줍니다.
그림에서 보시다시피 Compositional은 별개의 시각적 그룹으로 나누는 하나 이상의 Section를 가집니다. 각 Section은 표시할 데이터의 최소 단위인 개별 item Group를 만듭니다. Group은 Horizontal, Vertical 또는 Custom한 배열로 배치가 가능합니다. Group안에 배치되는 건 item입니다.
Section, Group, Item이 모여서 전체 레이아웃을 구성하게 됩니다.
그럼 직접 Compositional Layout를 구성해보겠습니다. 저는 이미 만들어둔 CollectionViewFlowlayout를 수정해보려고 합니다. Flowlayout의 코드는 이렇습니다.
private let flowLayout: UICollectionViewFlowLayout = { let flowLayout = UICollectionViewFlowLayout() flowLayout.scrollDirection = .horizontal flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width * 0.53) flowLayout.minimumInteritemSpacing = .zero flowLayout.minimumLineSpacing = .zero flowLayout.sectionInset = .zero return flowLayout }()
Swift
복사
해당 FlowLayout를 CollectionView에 적용하게 되면 이런 모습을 가집니다.
그럼 FlowLayout를 Compositional Layout 코드로 바꿔 볼까요?
FlowLayout를 Compositional로 반영하기 위해서 코드를 한 번 뜯어 볼게요.
scrollDirection: .horizontal
itemWidth: UIScreen.main.bounds.size.width
itemHeight: UIScreen.main.bounds.size.width * 0.53
spacing: none
sectionInset: none
저걸 어떻게 Compositional Layout으로 바꾸면 좋을까요?
먼저, UICollectionViewLayout를 반환하는 함수를 만들겠습니다. 그리고 메서드 내부에 UICollectionViewCompositionalLayout를 만들겠습니다. CompositionalLayout은 CollectionViewLayout의 한 유형이기 때문에 CompositionalLayout를 반환하겠습니다.
private func createLayout() -> UICollectionViewLayout { let layout = UICollectionViewCompositionalLayout { index, environment -> NSCollectionLayoutSection? in } return layout }
Swift
복사
이제 내부를 순서대로 채워 보겠습니다.
1.
Item
Item은 Group 내부에 속하는 작은 부분들 입니다. 셀이라고 보면 될 거 같네요. 셀의 width, height를 설정해주겠습니다.
let itemSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.53) ) let item = NSCollectionLayoutItem(layoutSize: itemSize)
Swift
복사
.fractionalWidth는 전체에서 비율을 나타냅니다. 안에 들어가는 값이 1.0이면 전체 width에 딱 맞게 width 값을 설정한다는 뜻입니다. height는 이전에 width의 0.53를 곱했으니깐, 이번엔 width 비율에 맞춰서 height를 정하겠습니다.
2.
Group
이제 Item를 묶어줄 그룹을 만들어 줍시다.
그림처럼 Group 하나가 Item 하나를 담는다면, Group도 Item의 크기와 동일해야 합니다. 따라서, width, height를 Item과 동일하게 해줍시다.
let groupSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.53) ) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
Swift
복사
3.
Section
Section에서는 contentInset과 Spacing를 .zero로 설정해줬습니다.
let section = NSCollectionLayoutSection(group: group) section.contentInsets = .zero section.interGroupSpacing = .zero return section
Swift
복사
그럼 잘 되는지 확인해봅시다.
스크롤이 밑으로 됩니다..
Section 부분에 코드를 한 줄 더 추가해주겠습니다.
section.orthogonalScrollingBehavior = .groupPaging
Swift
복사
다시 실행해보겠습니다. (੭˙ ˘ ˙)੭

 마치며

UICollectionViewCompositionalLayout를 사용하면 UICollectionViewFlowLayout를 사용하는 것보다 훨씬 유연한 Layout를 구성할 수 있습니다.
전체 코드는 해당 링크에서 확인하실 수 있습니다.

 참고 자료