이번에는 우리가 만들 세 개의 섹션에 대한 레이아웃을 잡는다.
나중에는 VM을 이용하여 데이터를 주입할 것이지만 지금은 그렇게 하지 않고 더미로 표시할 것이다.
첫 번째 섹션은 이미지만을 출력할 거라 1개, 두 번째는 Character가 가진 요소인 8개, 세 번째는 캐릭터마다 다른 숫자를 가진다. 임시로 20개라고 하자.
extension RMCharacterDetailViewController: UICollectionViewDelegate, UICollectionViewDataSource {
...
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch section {
case 0:
return 1
case 1:
return 8
case 2:
return 20
default:
return 1
}
}
...
}
Photo 섹션
첫번째 Photo 섹션에서는 Cell 하나만 표시하고 상대적으로 큰 cell을 가져야 한다.
높이의 0.5로 줘서 50%를 차지하게 하자.
private func createPhotoSectionLayout() -> NSCollectionLayoutSection {
let item = NSCollectionLayoutItem(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0)))
item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 10, trailing: 0)
let group = NSCollectionLayoutGroup.vertical(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(0.5)),
subitems: [item])
let section = NSCollectionLayoutSection(group: group)
return section
}
Info 섹션
두 번째 Info 섹션에서는 두 개의 칼럼을 가지는 그리드 형태를 만들고자 한다.
먼저 item의 너비를 50%로 설정하고 ContentsInset을 2씩 주자. 다음으로, 그룹에서 horizontal로 표시하게 명시한다. 마지막으로 subitems에 아이템을 추가해 2 열임을 알려주면 된다.
private func createInfoSectionLayout() -> NSCollectionLayoutSection {
let item = NSCollectionLayoutItem(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.5),
heightDimension: .fractionalHeight(1.0)))
item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(150)),
subitems: [item, item])
let section = NSCollectionLayoutSection(group: group)
return section
}
Episode 섹션
세번째 섹션은 조금 생각을 해봐야 하는데 에피소드라는 특성상 특정 캐릭터들은 끝없이 길어지는 Cell을 가질 가능성이 있다. 이를 방지하기 위해 데이터의 출력을 vertical이 아닌 horizontal로 처리하자
contentInset을 조금 조정하고 group에서 0.8로 너비를 조정하고 section에서 orthogonalScrollingBehavior = .groupPaging으로 행동을 조정했다.
private func createEpisodeSectionLayout() -> NSCollectionLayoutSection {
let item = NSCollectionLayoutItem(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0)))
item.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.8),
heightDimension: .absolute(150)),
subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
기능 분리
이제 위에서 만든 Layout 메서드들을 모두 VM으로 옮기고 private으로 되어 있는 접근 지정자를 public으로 수정하자. 아마 에러가 날텐데 이건 해당 VM이 Foundation으로 선언되어 있어서 생기는 문제다. UIKit으로 수정하자.
다음으로 View에서는 return 되는 섹션 레이아웃에 viewMode을 붙여주자.
private func createSection(for sectionIndex: Int) -> NSCollectionLayoutSection {
let sectionTypes = viewModel.sections
switch sectionTypes[sectionIndex] {
case .photo:
return viewModel.createPhotoSectionLayout()
case .episodes:
return viewModel.createEpisodeSectionLayout()
case .information:
return viewModel.createInfoSectionLayout()
}
}
끝
'Swift > Rick & Morty' 카테고리의 다른 글
[iOS] Rick&Morty - #17 Character Photo Cell (0) | 2023.03.15 |
---|---|
[iOS] Rick&Morty - #16 Character Detail ViewModels (0) | 2023.03.14 |
[iOS] Rick&Morty - #14 Compositional Layout (1) | 2023.03.12 |
[iOS] Rick&Morty - #13 Character Detail View(2) (0) | 2023.03.11 |
[iOS] Rick&Morty - #12 Image Loader (0) | 2023.03.09 |