ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] Compositional Layout - 헤더, 다양한 layout적용
    개발/Swift 2022. 11. 23. 15:16

    Modern Collection View 와 MVVM 패턴 가이드

     

    [iOS] Swift Modern Collection View & MVVM 패턴 가이드 강의 - 인프런

    MVVM 패턴과 Modern Collection View를 사용해 네트워킹을 구현하고, 다양하고 동적인 Collection View를 자유자재로 다룰 수 있게 됩니다., Swift iOS UI, 제대로 다루는 핵심 기술! 📲 iOS Swift 레이아웃 구현을

    www.inflearn.com

    헤더 추가하기

    헤더를 추가하기 위해 다음작업들이 필요하다

    1. 헤더 구현( UICollectionReusableView )
    2. 헤더 레지스터
    3. 헤더를 데이터소스에 추가
    4. 헤더를 레이아웃에 추가

    헤더를 레지스터하는 방법은 cell레지스터와 비슷하다

    collectionView.register(HeaderView.self, forSupplementaryViewOfKind: AlbumsViewController.sectionHeaderElementKind, withReuseIdentifier: HeaderView.reuseIdentifier)
    

    forSupplementaryViewOfKind : 레이아웃에 사용

    withReuseIdentifier: 데이터소스에 사용

    이제 헤더를 데이터소스에 추가하려면

    dataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) -> UICollectionReusableView? in
    	return headerViewdataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) -> UICollectionReusableView? in
          guard let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: HeaderView.reuseIdentifier, for: indexPath) as? HeaderView else { fatalError()}
          //indexPath 통해 섹션 인덱스 접근 가능
    
          return headerView
        }
    }

    이렇게 헤더뷰를 dequeueReusableSupplementaryView 통해 불러와 사용한다.

    이제 마지막으로 레이아웃에 추가한다

    let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
    let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: AlbumsViewController.sectionHeaderElementKind, alignment: .top)
    

    이렇게 헤더의 레이아웃을 잡은후

    let section = NSCollectionLayoutSection(group: group)
    section.boundarySupplementaryItems = [header]
    

    기존 section 레이아웃 boundarySupplementaryItems에 넣어주면 된다.

     

    섹션별로 다른 Cell 다른 레이아웃 섞기

    다른 레이아웃을 섞기위해서 다음 과정이 필요하다.

    1. cell 구현 (UICollectionViewCell)
    2. 레지스터
    3. 데이터소스에서 섹션별 분기
    4. 레이아웃 구현

    cell 구현 & 레지스터는 기존 방식과 같다 ( 패스)

    데이터소스에서 섹션별로 분기 처리해 섹센별로 다른 cell을 사용할수 있다.

    데이터 소스는 이런 구조로 생성된다.

    UICollectionViewDiffableDataSource<Section,AlbumItem>(collectionView: <#UICollectionView#>, cellProvider: <#(UICollectionView, IndexPath, AlbumItem) -> UICollectionViewCell?#>)
    (Datasource에 관련해는 다음에 알아보기로…)

    cellProvider 파라미터 안에 section 별로 셀을 넣어주면 된다.

     

    Datasource 코드

    dataSource = UICollectionViewDiffableDataSource
          <Section, AlbumItem>(collectionView: albumsCollectionView) {
            (collectionView: UICollectionView, indexPath: IndexPath, albumItem: AlbumItem) -> UICollectionViewCell? in
    		// cellProvider 부분
            
            //섹션을 따로 정의했음, 인덱스로 처리해도 무관
            let sectionType = Section.allCases[indexPath.section]
            switch sectionType {
            ///섹션별로 다른 cell 리턴
            case .featuredAlbums:
              guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FeaturedAlbumItemCell.reuseIdentifer, for: indexPath) as? FeaturedAlbumItemCell else {fatalError()}
              
              return cell
            default:
              guard let cell = collectionView.dequeueReusableCell(
                withReuseIdentifier: AlbumItemCell.reuseIdentifer,
                for: indexPath) as? AlbumItemCell else { fatalError("Could not create new cell") }
    
              return cell
            }

    UICollectionViewCompositionalLayout은

    이런 구조로 구성된다. 해당 레이아웃이 collectionview 생성시 들어간다.

    UICollectionViewCompositionalLayout { <#Int#>, <#NSCollectionLayoutEnvironment#> in
          <#code#>
        }
    

    위의 Int 파라미터가 섹션의 인덱스를 의미한다. 따라서 섹션별 다른 레이아웃 적용이 가능하다.

    func generateFeaturedAlbumsLayout(isWide: Bool) -> NSCollectionLayoutSection 
    

    위와같이 레이아웃을 리턴하는 함수 구현후 UICollectionViewCompositionalLayout 생성시에 원하는 섹션에 레이아웃을 넣어주면 된다.

    댓글

Designed by Tistory.