https://developer.apple.com/videos/play/wwdc2019/215
Advances in Collection View Layout - WWDC19 - Videos - Apple Developer
Collection View Layouts make it easy to build rich interactive collections. Learn how to make dynamic and responsive layouts that range...
developer.apple.com
Current state-of-the-art
CollectionView는 두 가지 클래스로 구성되는데요.
하나는 렌더링, 하나는 항목이 어디에 배치될 지 결정하는 역할을 합니다.
이 레이아웃이 추상적인 개념이라, 이를 활용하려면 서브클래싱을 해야 했습니다.
(상속 받아서 확장)
iOS 6부터 UICollectionViewFlowLayout이라는 구체적인 레이아웃 클래스가 제공되기 시작했고,
line-based layout이었기에 정해진 방향으로 아이템을 배치하다가,
가능한 공간이 부족해지면 다음 줄로 넘어가는 형태였습니다.
하지만 오늘날의 앱은 화면 크기도 다양해지고, 앱의 UI도 점점 복잡해지고 있습니다.
앱 스토어의 화면을 구현하라고 가정했을 때, Flow Layout로 구현할 수 있을까요?
대부분 바로 커스텀 레이아웃을 선택할텐데요,
하지만 커스텀 레이아웃은 너무 복잡합니다.

고려해야 할 것들이 것들이 너무 많아 불편합니다.
A new approach: Compositional Layout
그래서 Compositional Layout이 새롭게 등장했습니다.

Compositional Layout의 세 가지 특징은 다음과 같습니다.
1. 조합 가능성(Composability) - 단순한 요소들을 조합해 복잡한 레이아웃을 잘 구성하도록
2. 유연성(Flexibility)
3. 빠른 성능(Performance) - 최적화가 내장되어 있음
또한, 선언형 API(Declarative API)를 기반으로 작동되어 있습니다.
그런데, 왜 Composing 일까요?

컴포지셔널 레이아웃은
기본적으로 작은 레이아웃 단위들을 결합하여 더 큰 레이아웃을 구성하는 방식입니다.
아이템 개수를 아는 것과 상관 없이, 이 항목들이 특정 Layout Group 안에 배치되도록 설계하는 건데요.
중요한 건 기존의 번거로운 서브클래싱 없이도 동작한다는 장점이 있다는 것입니다.
단순 List 예제
단순한 List를 구현하는 예제입니다.

"이거 Flow Layout에서는 2줄이면 될 텐데, 왜 이렇게 복잡해 보이지?"
물론 Flow Layout이면 더 간단할 수도 있지만,
레이아웃이 복잡해질수록 코드가 점점 많아지는 Flow Layout과 다르게
컴포지셔널 레이아웃에서는 단순 새로운 요소만 추가하면 됩니다.
컴포지셔널 레이아웃에는 다음의 네 가지 타입이 존재합니다.

1. 아이템(Item)
2. 그룹(Group)
3. 섹션(Section) - 데이터 소스와 직접 연결
4. 레이아웃(Layout) - CollectionView 전체
이렇게 아이템 → 그룹 → 섹션 → 레이아웃 구조가 계속 반복되는 형식입니다.
컴포지셔널 레이아웃의 핵심 개념 중 하나는 Sizing인데요.
컴포지셔널 레이아웃은 모든 요소들이 자신의 크기에 대해 strong opinion을 갖고 있습니다.
UI는 2D 공간이기에, 모두 width와 height를 가지고 있고
이 값들은 NSCollectionLayoutDimension이라는 타입을 사용해 정의됩니다.

- 비율(Fractional) - 컨테이너의 크기에 대한 백분율로 지정
- 절대(Absolute) - 픽셀 단위로 정확한 크기를 지정
- 추정(Estimated) - 초기 크기를 추정, 이후 동적으로 조정
- 비율 기반 높이(Fractional Height) - 너비를 기준으로 비율을 유지하면서 크기를 결정
예를 들어, 아이템이 자신의 컨테이너의 50% 너비를 차지하도록 설정하거나,
높이를 컨테이너의 30%로 설정할 수도 있습니다.
Item

아이템은 화면에 표시되는 하나의 셀 또는 보조 뷰(supplementary view)를 의미합니다.
아이템을 생성할 때는 반드시 크기를 지정해야 합니다.
Group
그룹은 아이템을 포함하는 역할을 합니다.

수평(Horizontal) - 아이템들을 가로로 배치
수직(Vertical) - 아이템들을 세로로 배치
커스텀(Custom) - 직접 좌표를 지정하여 배치
커스텀 그룹을 사용하면 사용자 지정 레이아웃(원형이나 비대칭 배치 등)을 구현하는 것이 가능하고,
그룹 안에 그룹을 nesting하는 것 또한 가능합니다.
Section

섹션은 데이터 소스에서 제공하는 섹션과 1:1로 매핑됩니다.
Demos
✅ 예제: List layout

- 아이템을 정의
- 아이템을 그룹에 포함
- 그룹을 섹션에 포함
- 섹션을 최종 레이아웃으로 설정
✅ 예제: Grid Layout

위와 동일한 과정인데, 아이템의 너비를 그룹의 20% 로 설정하면, 5개의 열이 됩니다.
높이는 너비와 동일하게 설정했습니다.
✅ 아이템 간 Spacing 추가

Insets을 추가해서 아이템 사이에 여백을 줄 수도 있습니다.
✅ 열의 개수가 고정된 경우


✅ 여러 섹션마다 다른 레이아웃을 적용하려면?
- 첫 번째 섹션: 리스트(List)
- 두 번째 섹션: 5열(Grid)
- 세 번째 섹션: 3열(Grid)

SectionLayoutKind 지정할 수 있습니다.

이를 활용해, 위와 같이 섹션마다 다른 레이아웃이 그려지도록 지정할 수 있습니다.
✅ 반응형(Adaptive) 레이아웃
만약 기기의 너비가 넓어지면 자동으로 더 많은 열을 표시하고자 한다면?

layoutEnvironment를 활용하여 현재 화면 크기에 따라 동적으로 레이아웃을 조정할 수 있습니다.

예시 코드는 wideMode일 때, 아닐 때 구분지어서 분기해주고 있습니다.
Advanced layouts
CollectionView는 세 가지 기본적인 뷰 타입을 관리하는데요.
1. 셀(Cells) - 데이터를 표현하는 기본 요소
2. 보조 뷰(Supplementary Views) - 콘텐츠를 보완하는 뷰 (e.g., 배지, 헤더, 푸터)
3. 데코레이션 뷰(Decoration Views) - 배경 요소 등을 추가할 때 사용

가장 일반적인 보조 뷰는 배지(Badge), 헤더(Header), 푸터(Footer) 입니다.
Flow Layout에서도 헤더와 푸터를 고정하는 기능을 제공했지만,
컴포지셔널 레이아웃에서는 더 기능이 고도화 되었습니다.
컴포지셔널 레이아웃에서는 Supplementary Views를 특정 아이템이나 그룹에 고정시킬 수 있습니다.

예를 들어, 아이템의 오른쪽 상단 모서리에 배지를 추가 하고 싶다면,
아래와 같이 NSCollectionLayoutAnchor 를 사용하여 설정할 수 있습니다.

또 여기에서 fractionalOffset 을 사용하면, 아이템 영역 밖으로 조금 빠져나가도록 설정할 수도 있습니다.

✅ Header와 Footer 추가하는 방법

헤더와 푸터는 일반 보조 뷰와는 약간 다릅니다.
헤더나 푸터가 추가되면, 기존 콘텐츠를 가리지 않고 전체 영역이 확장됩니다.
이를 위해 Boundary Supplementary Item을 사용하는데요.

여기서 .top 을 설정하면, 헤더가 섹션의 맨 위에 고정 됩니다.
그리고 pinToVisibleBounds 옵션을 활용하면, 스크롤할 때 헤더가 고정되게 할 수도 있습니다.
✅ 데코레이션 뷰(Decoration View)

데코레이션 뷰는 배경 요소를 추가할 때에 사용됩니다.
이를 활용해 각 섹션마다 배경을 다르게 지정할 수 있습니다.
✅ 셀 크기를 자동으로 조정 (Self-Sizing)
컴포지셔널 레이아웃에서는 각 X, Y축에 대해 개별적으로 크기를 조정할 수 있다고 하는데요.
예를 들어, 헤더의 경우, 너비는 고정된 상태에서 높이만 동적으로 조정 되도록 설정할 수 있습니다.
✅ 중첩 그룹(Nested Groups)

컴포지셔널 레이아웃에서는 그룹을 중첩해서 복잡한 레이아웃을 구현할 수도 있는데요.
예를 들어, 위 예시처럼
- 왼쪽에는 큰 아이템 이 있고,
- 오른쪽에는 세로로 배치된 작은 아이템 그룹
을 구현하고자 한다면,

- 작은 아이템 두 개를 포함한 세로 그룹 생성
- 세로 그룹과 큰 아이템을 포함하는 가로 그룹 생성
하는 방식으로 중첩된 레이아웃을 쉽게 구현할 수 있습니다.
✅ 콜렉션 뷰 내부에 또 다른 콜렉션 뷰 중첩
이 기능이 iOS 13의 App Store 디자인을 구현할 때도 사용되었다 하는데요.

App Store에는 세로 스크롤 내부에 가로 스크롤 뷰가 포함되어 있습니다.
이전에는 이를 구현하기 위해 각 섹션마다 별도의 CollectionView를 생성해야 했지만,
컴포지셔널 레이아웃에서는 아래와 같이 한 줄만 추가해주면 됩니다.


- 연속 스크롤(Continuous) - 일반
- 그룹 경계 정렬(Continuous Group Leading Boundary) - 그룹 단위로 정렬
- 페이지 스크롤(Paging) - 한 페이지씩 이동
- 그룹 페이지 스크롤(Group Paging) - 그룹 단위로 페이지 스크롤
- 그룹 중앙 정렬 페이지 스크롤(Group Paging Centered) - 그룹이 중앙에 위치
'WWDC' 카테고리의 다른 글
[WWDC] Embrace Swift generics (1) | 2025.02.08 |
---|---|
[WWDC] Make blazing fast lists and collection views (0) | 2025.02.05 |
[WWDC] Advances in UI Data Sources (0) | 2025.02.03 |
[WWDC] ARC in Swift: Basic and beyond (0) | 2024.12.20 |
[WWDC] Understanding Swift Performance (0) | 2024.12.14 |