UICollectionViewCompositionalLayout in iOS 13+

ios dev·2021년 10월 2일
0

UICollectionViewCompositionalLayout

  • compositional layout은 collectionView layout의 한 유형이다.
  • 구성 가능(composable)하고 유연(flexible)하며 빠르도록(fast) 설계되었기 때문에 각각의 구성 요소(component)를 전체 layout으로 결합(combining)하거나 합성(compositing)해 content에 대한 모든 종류의 시각적인 배열을 구축할 수 있다.
  • compositional layout은 layout을 별개의 시각적 그룹으로 나누는 하나 이상의 section으로 구성된다.
    section은 표시하려는 데이터의 가장 작은 단위인 itemgroup으로 구성된다.
    groupitem을 가로 행, 세로 열 또는 사용자 지정 배열로 배치할 수 있다.


item에서 group으로, group에서 section으로 결합한 뒤, 전체 layout으로 구성 요소를 결합한다.

// basic list layout 만들기
func createBasicListLayout() -> UICollectionViewLayout {
  // item 구성
  let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                        heightDimension: .fractionalHeight(1.0))

  let item = NSCollectionLayoutItem(layoutSize: itemSize)

  // group 구성
  let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                         heightDimension: .absolute(44))

  let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                 subitems: [item])

  // section 구성
  let section = NSCollectionLayoutSection(group: group)

  // CompositionalLaytou 구성
  let layout = UICollectionViewCompositionalLayout(section: section)
  
  return layout
}


NSCollectionLayoutSize

  • collectionView에 있는 item의 widthheight.
  • NSCollectionLayoutSize는 'width dimension과 height dimension'(NSCollectionLayoutDimension)으로 이루어진다.

NSCollectionLayoutDimension

: collectionView에서 item 크기(width 또는 height)의 개별 치수(dimension).

  • absolute
    : 절대값, 정확한 치수를 지정.
let absoluteSize = NSCollectionLayoutSize(widthDimension: .absolute(44),
                                          heightDimension: .absolute(44))

  • estimated
    :
    데이터가 로드되거나 시스템 글꼴 크기가 변경되는 경우와 같이 runtime에 contents의 크기가 변경될 수 있는 경우, 예상 값을 사용한다.
    (초기 추정 크기를 제공하면 시스템이 나중에 실제 값을 계산.)
let estimatedSize = NSCollectionLayoutSize(widthDimension: .estimated(200),
                                           heightDimension: .estimated(100))

  • fractional
    :
    분수값을 사용해 item 컨테이너의 dimension을 기준으로 상대적인 값을 정의한다. 이 옵션을 사용하면 가로 세로 비율을 쉽게 지정할 수 있다.
let fractionalSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.2),
                                            heightDimension: .fractionalWidth(0.2))


NSCollectionLayoutItem

collectionView layout의 가장 기본적인 구성 요소.

  • item은 collectionView에서 개별 contents의 크기, 공간 및 정렬하는 방법에 대한 청사진(blueprint)이다.
  • item은 화면에 렌더링된 single view를 나타낸다.
  • 일반적으로 item은 cell이지만 header, footer와 같은 supplementary view(보조 view)가 될 수도 있다.
  • 예를 들면, item은 사진 앱에서는 하나의 사진을 나타낼 수도 있고,
    appStore에서는 개별 앱에 대한 정보를 표시하는 cell이 될 수도 있다.
  • item을 group으로 결합해 각 item이 서로 어떻게 배열되는지 결정할 수 있다.



NSCollectionLayoutGroup

path를 따라 item(a set of items)을 배치하는 container.

  • group은 item이 어떻게 배치되는지 결정한다.
  • group은 item을 a horizontal row, a vertical column 또는 custom arrangement에 배치할 수 있다.
  • group은 item이 렌더링되는 방법에 대한 규칙을 결정하지만 그 자체로는 내용을 렌더링하지 않는다.

  • groupwidth dimensionheight dimension에 대한 자체 크기를 지정할 수 있다.
  • groupNSCollectionLayoutItem의 subClass이기 때문에 item처럼 작동합니다.
  • group다른 item 및 group과 결합해 복잡한 layout을 만들 수 있다.
  • group을 구성한 후에는 해당 group을 사용해 section을 초기화해야 한다.



NSCollectionLayoutSection

group(a set of groups)을 고유한 시각적 그룹으로 결합하는 container.

  • collectionView layout에는 하나 이상의 section이 있다.
  • sectionlayout을 별개의 조각으로 구분하는 방법을 제공한다.
  • section은 collectionView의 다른 section과 layout이 같을 수도 있고 다를 수도 있다.
  • section의 layout은 group의 속성에 의해 결정된다.
  • section은 다른 section과 구별하기 위한 고유한 background, header 및 footer를 가질 수 있다.



Usage

private func layout() -> UICollectionViewLayout {
        return UICollectionViewCompositionalLayout { [weak self] section, environment -> NSCollectionLayoutSection? in
            guard let self = self else { return nil }
            switch section {
            case 0: return self.createBannerSection(height: self.mainBannerHeight)
            case 1: return self.createLocationSection()
            case 2: return self.createCategorySection()
            case 5: return self.createBannerSection(height: self.subBannerHeight)
            default: return self.createBasicSection()
            }
        }
    }
    
    private func createBasicSection() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3),
                                              heightDimension: .estimated(230))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = .init(top: 0, leading: 5, bottom: 0, trailing: 5)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.9),
                                               heightDimension: .estimated(230))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                       subitem: item,
                                                       count: 3)
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .continuous
        let sectionHeader = createSectionHeader()
        section.boundarySupplementaryItems  = [sectionHeader]
        section.contentInsets = .init(top: 10, leading: 5, bottom: 20, trailing: 5)
        return section
    }
    
    private func createSectionHeader() -> NSCollectionLayoutBoundarySupplementaryItem {
        let layoutSectionHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                                             heightDimension: .absolute(30))
        let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: layoutSectionHeaderSize,
                                                                        elementKind: UICollectionView.elementKindSectionHeader,
                                                                        alignment: .topLeading)
        return sectionHeader
    }




cf.
https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayout
https://developer.apple.com/documentation/uikit/nscollectionlayoutsize/
https://developer.apple.com/documentation/uikit/nscollectionlayoutdimension
https://developer.apple.com/documentation/uikit/nscollectionlayoutitem/
https://developer.apple.com/documentation/uikit/nscollectionlayoutgroup
https://developer.apple.com/documentation/uikit/nscollectionlayoutsection

0개의 댓글