[UIKit] Spotify Clone: Browse UI 1

Junyoung Park·2022년 9월 2일
0

UIKit

목록 보기
8/142
post-thumbnail

Building Spotify App in Swift 5 & UIKit - Part 8 (Xcode 12, 2021, Swift 5) - Build App

Spotify Clone: Browse UI 1

구현 목표

  • 데이터 종류에 따라 UICollectionView 레이아웃 커스텀 → 섹션 별 구별

구현 태스크

  1. 섹션에 따라 UICollectionView 배치가 달라지는 레이아웃을 결정
  2. 섹션 내 아이템, 아이템의 집합인 그룹, 그룹이 들어가는 섹션의 해당 위치 및 정렬 방법, 선택 방법 등을 레이아웃 내에서 커스텀한다.

핵심 코드

private var collectionView: UICollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewCompositionalLayout { sectionIndex, _ -> NSCollectionLayoutSection? in
        return HomeViewController.createSectionLayout(section: sectionIndex)})
  • UICollectionView 커스텀 코드
  • 디폴트 UICollectionViewCell 사용
  • UICollectionView를 그리는 데 필수적인 레이아웃은 섹션 인덱스에 따라서 동적으로 변경

    레이아웃을 통해 각 섹션 내 아이템의 수직/수평 방향 배열을 어떻게 할 것인지 결정할 수 있다! 물론 각 아이템 별 크기, 공백 등 다양하게 결정할 수 있는, "UICollectionView를 자유자재로 그리는 방법".

private static func createSectionLayout(section: Int) -> NSCollectionLayoutSection {
        switch section {
        case 0:
            let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(1)))
            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
            // Group
            let verticalGroup = NSCollectionLayoutGroup.vertical(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .fractionalWidth(1.0),
                    heightDimension: .absolute(390)
                ),
                subitem: item,
                count: 3)
            
            let horizontalGroup = NSCollectionLayoutGroup.horizontal(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .fractionalWidth(0.9),
                    heightDimension: .absolute(390)
                ),
                subitem: verticalGroup,
                count: 1)
            
            // Section
            let section = NSCollectionLayoutSection(group: horizontalGroup)
            section.orthogonalScrollingBehavior = .groupPaging
            return section
        case 1:
            let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .absolute(200), heightDimension: .absolute(200)))
            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
            // Group
            let verticalGroup = NSCollectionLayoutGroup.vertical(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .absolute(200),
                    heightDimension: .absolute(400)
                ),
                subitem: item,
                count: 2)
            
            let horizontalGroup = NSCollectionLayoutGroup.horizontal(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .absolute(200),
                    heightDimension: .absolute(400)
                ),
                subitem: verticalGroup,
                count: 1)
            
            // Section
            let section = NSCollectionLayoutSection(group: horizontalGroup)
            section.orthogonalScrollingBehavior = .continuous
            return section
        case 2:
            let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
            // Group
            
            let group = NSCollectionLayoutGroup.vertical(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .fractionalWidth(1),
                    heightDimension: .absolute(80)
                ),
                subitem: item,
                count: 1)
            
            // Section
            let section = NSCollectionLayoutSection(group: group)
            return section
        default:
            let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(1)))
            item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
            // Group
            let group = NSCollectionLayoutGroup.vertical(
                layoutSize: NSCollectionLayoutSize(
                    widthDimension: .fractionalWidth(1.0),
                    heightDimension: .absolute(390)
                ),
                subitem: item,
                count: 1)
            // Section
            let section = NSCollectionLayoutSection(group: group)
            section.orthogonalScrollingBehavior = .groupPaging
            return section
        }
    }
  • UICollectionView의 섹션 별 레이아웃은 개별 아이템, 개별 아이템의 집합인 그룹, 그룹이 배열되는 섹션으로 구별
  • 섹션 아이디 값에 따라서 서로 다른 배열 가능하도록 switch-case 문 사용
  • 아이템의 레이아웃 사이즈에 따라 크기 결정
  • 아이템이 수직으로 정렬될 verticalGroup
  • 수직으로 정렬된 verticalGroup을 일종의 서브 아이템으로 취급하는 수평 그룹 horizontalGroup 등 이중 배치 가능
  • 섹션 내 배열되는 최종 그룹을 섹션에 넣은 뒤 스크롤 방식을 연속적/페이징 적용 등 개별 선택 가능

구현 화면

  • 1번 섹션은 페이지 단위, 2번 섹션은 연속적으로 섹션 내 그룹 아이템이 넘어간다는 점이 특징적
  • 수직으로 아이템을 몇 개 쌓고 수평으로 확장할 것인지, 수평으로 아이템을 몇 개 쌓고 수직으로 확장할 것인지 커스텀이 가능하기 때문에 네 가지 방향(종횡) 모두 가능한 UICollectonView의 확장성을 제대로 활용하는 방법

UICollectionView의 레이아웃은 아이템, 아이템이 이루는 그룹, 그룹이 이루는 섹션을 통해 구성된다. 수평, 수직 등 방향 및 각 아이템과 그룹의 크기, 이동 방법에 따라 구성되는 뷰가 달라지기 떄문에 커스텀에 주의하자!

profile
JUST DO IT

0개의 댓글