[Swift] Compositional Layout - 레이아웃 그려보기
Modern Collection View 와 MVVM 패턴 가이드
다양한 사이즈 형태의 collection view를 구현 하기 위해 Group을 잘 짜줘야 한다.
let group = NSCollectionLayoutGroup.vertical(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(16/9)),
subitems: [다양한 그룹들])
(각 그룹들의 높이는 고정값으로 지정했으니 무시)
위 그룹의 subItems 안에 다양한 타입의 그룹이 들어갈것이고
해당 그룹들은 vertical 하게 들어갈것이다.
다음 예시를 통해 여러 타입의 collectionview 를 그려볼것이다.
가장 먼저 1번 - 너비는 width * 1
높이는 width * 2/3 크기를 가지고 있다.
let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
//padding 추가
fullItem.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
해당 fullItem을 가지고 레이아웃을 리턴한다
func generateLayout() -> UICollectionViewLayout {
let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
fullItem.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(16/9)), subitems: [fullItem])
let section = NSCollectionLayoutSection(group: group)
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
그룹 안에 해당 fullitem을 너어주면 모든 아이템들이 fullItem 사이즈로 그려진다.
2번 레이아웃
2번 은 두가지 타입으로 나뉜다.
왼쪽의 큰 메인이미지, 오른쪽의 서브이미지그룹
이 두 타입을 그룹으로 묶어야한다. (2번 그룹이라 하자)
2번 그룹의 너비는 width * 1 높이는 width * 4/9 로 지정해줬다.
그리고 두 타입(메인이미지 + 서브그룹) 이미지는 horizontal로 정렬 된다. ( 좌 우로 그려지므로)
let mainAndSubGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [MainItem, subGroup])
이렇게 그룹을 만들것이다.
구성은 이렇게 된다
- 전체 그룹
- 2번 그룹
- 메인이미지
- 서브이미지 그룹
- 2번 그룹
이제 들어갈 아이템을 그려본다.
메인이미지는 width * 2/3
높이 height * 1 (2번 그룹의 기준) 를 가진다.
let mainItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(2/3), heightDimension: .fractionalHeight(1.0)))
서브 이미지 그룹의 너비는 width * 1/3
높이는 height * 1 일것이고 ( 2번 그룹 기준)
위아래로 두개 들어갈 서브 이미지의 너비는 width * 1
높이 height * 1/2 사이즈이다.
let subItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1/2)))
let subGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)), subitem: subItem, count: 2)
이제 mainAndSubGroup 을 그룹에 넣어주면
이렇게 fullItem, mainAndSubGroup 식으로 반복된다.
4번 레이아웃
4번은 2번을 반대로 하면 된다. 이미 구현했으니 순서만 바꾼 그룹을 만들면 된다.
let subGroupAndMain = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [subGroup, mainItem])
3번 레이아웃
3번 - 너비 width * 1/3 인 아이템들을 그룹에 넣어주면된다.
let trippleItme = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)))
let trippleGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/9)), subitem: trippleItme, count: 3)
전체코드
func generateLayout() -> UICollectionViewLayout {
let contentInset = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
fullItem.contentInsets = contentInset
let mainItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(2/3), heightDimension: .fractionalHeight(1.0)))
mainItem.contentInsets = contentInset
let subItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1/2)))
subItem.contentInsets = contentInset
let trippleItme = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)))
trippleItme.contentInsets = contentInset
let trippleGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/9)), subitem: trippleItme, count: 3)
let subGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)), subitem: subItem, count: 2)
let mainAndSubGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [mainItem, subGroup])
let subGroupAndMain = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [subGroup, mainItem])
let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(16/9)), subitems: [fullItem, mainAndSubGroup, trippleGroup, subGroupAndMain])
let section = NSCollectionLayoutSection(group: group)
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
참조 : https://www.kodeco.com/5436806-modern-collection-views-with-compositional-layouts