UICollectionViewFlowLayout 배우기

고라니·2023년 9월 7일
0

TIL

목록 보기
30/67

UICollectionView는 UITableView와 달리, 다양한 형태의 아이템 표시와 사용자 정의 레이아웃을 제공하여 개발자들에게 큰 유연성을 제공한다. 제공하는 레이아웃중 많이 사용되는 CollectionViewFlowLayout에 대해 알아보자

UICollectionViewFlowLayout?

UICollectionViewFlowLayout는 UICollectionView의 아이템들을 어떻게 배치할지 결정하는 레이아웃 중 하나다. 다양한 속성들을 알아보도록 하자.

Flow Layout은 UICollectionView에 자주 사용되는 레이아웃이다. 이름대로 자연스럽게 흐르듯 아이템들을 순차적으로 배치하며, 한 행의 공간이 모두 채워지면 다음 행으로 넘어간다. (선형 배치)

UICollectionViewFlowLayout을 사용하여 아이템의 크기, 행 간격, 섹션 여백 등 다양한 레이아웃 속성을 지정할 수 있다. 유연하고 동적인 인터페이스를 만들 수 있다.

주로 그리드 형태에 많이 사용하지만 다양한 형태로 표현하는것도 가능

플로우레이아웃 구성 단계

  1. 플로우레이아웃 객체를 만들고 컬렉션 보기에 할당.
  2. 셀의 너비와 높이 설정
  3. 필요에 따라 line과 item의 간격 설정
  4. 섹션 footer, header를 사용하는 경우 크기를 지정해준다.
  5. 레이아웃의 스크롤 방향을 설정한다.

레이아웃의 스크롤 방향은 기본적으로 세로 방향이다, footer와 header의 크기는 기본적으로 0이기때문에 화면에 나타나지 않는다. 사용하기 위해서는 0보다 큰 수치로 설정해야 한다.


UICollectionViewFlowLayout의 주요 속성

1. 아이템(Cell) 크기

UICollectionView에서 아이템들의 크기를 지정하는 방법은 크게 세 가지가 있다.

  • 동일한 크기의 아이템: itemSize속성을 사용하여 모든 셀의 크기를 지정한다. 이 방법은 모든 셀이 동일한 크기일 때 가장 효과적으로 사용할 수 있다.

  • 다양한 크기의 아이템: UICollectionViewDelegateFlowLayout의 collectionView:layout:sizeForItemAtIndexPath메서드를 구현 하여 각 셀의 크기를 지정할 수 있다. 제공된 인덱스에 따라 해당 아이템의 크기를 반환한다. 동일한 라인에 있는 아이템들은 수직으로 중앙에 배치되며, 해당 라인의 전체 높이나 너비는 그 라인에서 가장 큰 아이템의 크기에 의해 결정된다.

func collectionView(UICollectionView, layout: UICollectionViewLayout, sizeForItemAt: IndexPath) -> CGSize
  • 추정된 크기의 아이템: estimatedItemSize 속성을 사용하여 아이템의 추정 크기를 지정할 수 있다. 이 방법은 주로 Auto Layout을 사용하여 셀의 크기를 동적으로 결정할 때 사용된다. 실제 아이템 크기는 런타임에 결정되며, 스크롤 성능 최적화를 위해 사용된다. (사실 아직까진 잘 이해가 되지 않는다.)

2. 간격(Spacing)

동일한 라인에 있는 아이템들 사이, 그리고 연속되는 라인 사이의 최소 간격을 지정할 수 있다.

  • 아이템 간 최소 간격(Interitem Spacing)
    아이템 간의 간격은 지정한 최소 간격보다 클 수 있다. 아이템을 배치할 충분한 공간이 없을 경우 다음 라인으로 배치한다. 라인에 딱 맞게 배치될 경우, 아이템 간의 간격은 지정한 최소 간격과 같게 된다. 하지만 라인 끝에 공간이 있다면, 간격이 자동으로 조절되어 균등하게 배치된다.

// 아이템 간의 최소 간격을 정의한다.
var minimumInteritemSpacing: CGFloat
  • 라인 간 최소 간격(Line Spacing)
    아이템 크기가 다를 경우, 스크롤 방향에 따라 각 라인에서 가장 큰 아이템 기준으로 해당 아이템 간의 간격을 최소 간격으로 설정한다. 세로 스크롤의 경우 레이아웃에서는 각 라인의 가장 높은 아이템 기준으로 간격이 설정된다.

// 라인 간의 최소 간격을 정의한다.
var minimumLineSpacing: CGFloat

아이템과 라인 간의 간격은 섹션별로 다를 수 있다.minimumLineSpacing과 minimumInteritemSpacing 속성을 사용하거나, collectionView:layout:minimumLineSpacingForSectionAtIndex: 및 collectionView:layout:minimumInteritemSpacingForSectionAtIndex: 메서드를 통해 동적으로 지정할 수 있다고 한다.

그런데 속성을 통해 지정하는것과 델리게이트 메서드를 통해 지정하는 것의 차이가 뭘까? 동적으로 지정할 수 있다는건 어떤 이유일까?
minimumLineSpacing과 minimumInteritemSpacing 속성을 사용하면, 모든 섹션에 대해 동일한 간격이 설정된다, 반면 델리게이트 메서드들을 사용하면 인덱스로 접근이 가능하여 개별적으로 다른 간격을 지정할 수 있다. 그렇기 때문에 각 섹션마다 다른 값을 설정할수 있기 때문에 동적이라고 표현하고 있다.

3. 컨텐츠 여백(Section Insete)

Section Inset응 사용하여 콘텐츠의 여백을 설정할 수 있다.

SectionInset 속성은 콘텐츠 여백을 조절하는 데 사용된다. 여기서 여백이란, 셀과 섹션의 헤더 또는 푸터, 그리고 콘텐츠의 양쪽 여백을 의미한다.

여백은 셀을 배치할수 있는 공간을 줄이므로, 한 라인에 배치될 수 있는 셀의 수를 제한하는데 사용 가능하다.

아래의 이미지는 세로로 스크롤되는 플로우 레이아웃에서 여백이 콘텐츠에 어떻게 여향을 미치는지 보여준다.


UICollectionViewDelegateFlowLayout

위의 설명에서 UICollectionViewDelegateFlowLayout프로토콜 메서드에 대한 내용들을 언급했었다. 이 프로토콜은 UICollectionViewFlowLayout객체와 상호작용하여 레이아웃을 조정할 수 있는 메서드가 정의되어 있다. 주요 메서드들을 알아보자

// 지정된 셀의 크기를 변환하는 메서드
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout, 
            sizeForItemAt indexPath: IndexPath) -> CGSize

// 지정된 섹션의 여백을 반환하는 메서드
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout, 
                   insetForSectionAt section: Int) -> UIEdgeInsets

// 지정된 섹션의 행 사이 간격 최소 간격을 반환하는 메서드
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout,
                   minimumLineSpacingForSectionAt section: Int) -> CGFloat

// 지정된 섹션의 셀 사이의 최소간격을 반환하는 메서드
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout,
                   minimumInteritemSpacingForSectionAt section: Int) -> CGFloat

// 지정된 섹션의 헤더뷰의 크기를 반환하는 메서드, 크기를 지정하지 않으면 화면에 보이지 않는다.
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout,
                   referenceSizeForHeaderInSection section: Int) -> CGSize

// 지정된 섹션의 푸터뷰의 크기를 반환하는 메서드. 크기를 지정하지 않으면 화면에 보이지 않는다.
optional func collectionView(_ collectionView: UICollectionView, 
                   layout collectionViewLayout: UICollectionViewLayout,
                   referenceSizeForFooterInSection section: Int) -> CGSize

마치면서

아이템들을 어떻게 배치할지 설정할 수 있는 레이아웃 중 하나인 UICollectionViewFlowLayout을 알아봤다. 여러 속성과 UICollectionViewDelegateFlowLayout를 통해 간격들을 설정할 수 있다. 아직 직접 사용해보지 않아서 헷갈리는 부분이 있다, 바로 다음글에서 어떻게 사용하는지 구현해보겠다.

참고: 애플 공식문서, 부스트캠프 iOS프로그래밍

profile
🍎 무럭무럭

0개의 댓글