본문 바로가기
개발/iOS

[iOS] UICollectionView

by 마자용 2022. 3. 12.

⚠️ 읽기 전 참고

본문은 컬렉션 뷰를 구현하는 법에 관한 게시글이 아닌,
구현을 위해 필요한 클래스와 프로토콜에 대해 알아보는 글입니다!

 



iOS에서 가장 대표적이고 많이 쓰이는 UI 구성 방식은 리스트 형태로 구성된 화면일 것이다.
이를 구현하기 위해서는 UIView들을 나열하거나, UIScrollView 안에 UIStackView를 넣거나, UITableView를 사용하는 방법 등을 이용할 수 있다.
하지만 들어가는 리스트가 격자 형태(Grid)이거나 가로로 스크롤이 필요한 경우가 있다면 상황이 복잡해진다.
이러한 상황들을 포함해서 반복되는 복잡한 UI를 구성하기 위한 방법으로 UICollcetionView를 사용한다.


UICollectionView

- 정의: 유연하게 변경 가능한 레이아웃을 사용하여 특정 타입 형태로 정렬된 데이터 집합을 표시하는 방법
- 특징

  • 행과 열의 나열 뿐만이 아닌, 다양한 배열 형태로 구현이 가능하다.
    • Grid, Stack, 원, 동적으로 변하는 레이아웃 등
  • Data와 해당 Data를 표시하는 데 사용되는 시각적 요소를 엄격하게 구분한다. (= 책임을 분리한다)
    • 데이터의 보관과 표시를 별도로 구현한다.
    • 뷰들을 배치하고 속성을 지정하는 Layout 객체와 함께 작업을 수행한다.
    → 데이터 영역과 레이아웃 영역이 분리가 되어 각자의 역할에 맞는 정보를 제공하게 한다.

- 구현

Purpose Classes / Protocols
최상위 - UICollectionView
- UICollectionViewController
데이터 관리 - UICollectionViewDataSource (Protocol)
- UICollectionViewDelegate (Protocol)
표시 - UICollectionResuableView
- UICollectionViewCell
레이아웃 - UICollectionViewLayout
- UICollectionViewLayoutAttributes
- UICollectionViewUpdateItem
레이아웃 구성 - UICollectionViewFlowLayout
- UICollectionViewDelegateFlowLayout (Protocol)

 

1. UICollectionView, UICollectionViewController

- 시각적인 요소 정의
- UIScollView 상속
- Layout 정보 기반 데이터 표시
- UICollectionViewController는 UICollectionView를 뷰 컨트롤러 수준에서 관리할 수 있도록 해주는 것.

2-1. UICollectionViewDataSource

- 필수 요소
- Content 관리 및 Content 표시에 필요한 View 생성

2-2. UICollectionViewDelegate

- 선택 요소
- 특정 상황에서 View가 동작하도록 custom.

3. UICollectionViewReusableView, UICollectionViewCell

- 각각의 item, Header, Footer 등
- 재사용 가능
- UICollectionView에 표시되는 모든 뷰들은 UICollectionViewReusableView의 인스턴스.

  • 왜냐면 컬렉션뷰 → 스크롤 → 안 보였던 내용들을 보여주기 위해 재사용 메커니즘을 사용하니까

- 레이아웃 표현 시 contentView에 적용한다.

  • contentView라는 기본 객체가 superView가 되고, 그 위에 서브 뷰(= cell)들을 올리는 것이다.

 

4. UICollectionViewLayout, UICollectionViewLayoutAttributes, UICollectionViewUpdateItem

- 각 항목의 배치와 같은 시각적 스타일을 담당
- View를 직접 소유하지 않는 대신 Attributes를 생성

  • 컬렉션 뷰가 적용할 수 있도록 속성만 알려준다는 소리임
  • 데이터 항목 수정 시 UpdateItem 인스턴스를 수신
    • ex - 삽입, 삭제, 이동 등

- 코드 예시

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
        super.preferredLayoutAttributesFitting(layoutAttributes)
        let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
        var frame = layoutAttributes.frame
        frame.size.height = ceil(size.height)
        layoutAttributes.frame = frame
        return layoutAttributes
    }

 

5. UICollectionViewFlowLayout, UICollectionViewDelegateFlowLayout

- Grid, lind-based 레이아웃을 구현하거나, 레이아웃 정보를 동적으로 custom 하는 데 사용
- 적용

  1. FlowLayout 객체 생성 → CollectionView에 할당
  2. 셀 너비, 높이 설정
  3. 스크롤 방향 설정 (기본값 = vertical)
  4. 선택 사항
    • items, lines 간격
    • Header, Footer의 사이즈 명시

- 코드 예시

let pillInfoCollectionView = UICollectionView(frame: .zero, collectionViewLayout: .init()).then {
        let layout = UICollectionViewFlowLayout()
        layout.estimatedItemSize = CGSize(width: UIScreen.main.bounds.size.width - 40, height: 166)
        layout.footerReferenceSize = CGSize(width: UIScreen.main.bounds.size.width - 40, height: 132)
        layout.headerReferenceSize = CGSize(width: UIScreen.main.bounds.size.width - 40, height: 48)
        layout.minimumInteritemSpacing = 11
        layout.sectionInset = UIEdgeInsets(top: 11, left: 0, bottom: 16, right: 0)
        layout.scrollDirection = .vertical
        $0.backgroundColor = .clear
        $0.collectionViewLayout = layout
        $0.register(PillInfoCollectionViewCell.self)
        $0.register(PillInfoHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: PillInfoHeaderView.reuseIdentifier)
        $0.register(PillInfoFooterView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: PillInfoFooterView.reuseIdentifier)
        $0.showsVerticalScrollIndicator = false
    }

 


👀 정리

 


 

참고
- About iOS Collection Views
- UICollectionView
- UICollectionViewFlowLayout


👻 이어지는 게시글 - UICollectionViewCompositionalLayout (작성 예정 ...)

댓글