[WWDC2019] Advances in CollectionView Layout
CollectionView Layout의 발전 목차
CollectionView의 현재 기술 (current state of the art)
(iOS, tvOS, MacOS) 새로운 접근 방식 (a new approach)
Demo
고급 기능 (advanced layouts)
1. CollectionView의 현재 기술 (current state of the art)
UICollectionViewFlowLayout
CollectionViewLayout
Layout을 정의하기 위해 두 가지 역할을 가진 클래스로 추상화되어있다.
rendering을 하는 class
collectionView Layout이 어디로 가는지?에 대해 책임을 지는 class
CollectionView Layout은 추상화되어있기 때문에 사용하려면 항상 Subclassing을 해야한다.
이것을 Concrete type으로 정의한 것이 iOS 6에서 발표했던 CollectionView Flow Layout이다.
CollectionViewFlowLayout
line based layout system이었기 때문에, iOS6을 사용했던 환경에서 매우 유용하게 사용됐다.
(2018 WWDC 영상 참고) 단순히 Line들을 배치하고, 축을 기반으로 배치해서 Layout을 구성할 수 있다.
매우 간단하고, 추론이 쉬우며, 빠르다는 장점이 있다.
하지만 요즘에 이종화되는 기기와, 다양한 custom layout이 나오면서 UI가 매우 복잡해졌다.
복잡해진 UI로 인해 발생하는 문제점을 살펴보자.
Untitled AppStore의 메인화면을 구성하기 위해 우리는 다양한 컴포넌트를 고민할 것이다.
다양한 모양의 Cell이 존재하기 때문에, CollectionView를 선택했다고 가정하자.
이때, “Flow”를 표현할 수 있을지 고민하기 시작하자마자 CollectionView 사용을 포기하게 된다. (이유는 몰까)
Custom Layout을 설계할 때 발생할 수 있는 문제점
Boilerplate code
Performance considerations
Supplementary and decoration view challenges
CollectionView에서 관리할 수 있는 View, DecorationView는 CustomLayout에서 까다롭게 작용한다.
Self-sizing challenges
⇒ 이 문제들을 해결하기 위해 Flow와 동일한 Concrete class인 새로운 플랫폼을 도입했으며, 이것이 바로 Compositional Layout이다.
2. 새로운 접근 방식 (a new approach)
Compositional Layout의 개념
Compositional Layout의 중심 개념 3가지
Composable
간단한 것을 이용해서 복잡한 것을 만든다.
Flexible
유연하게 설계되어, 어떤 레이아웃이든 작성할 수 있다.
Fast
자체 최적화를 수행하여 빠르다.
Compositional Layout은 Layout을 설명하거나, 정의하는 선언형 API이다.
Compositional Layout의 활용
Composing small layout groups together
작은 레이아웃을 만들고, 이들을 조합해서 더 큰 레이아웃을 구성한다.
Layout groups are line-based
FlowLayout의 장점을 이어가기 위해 line based에 따라 레이아웃을 그릴 수 있다. (굉장히 많은 UI)
작은 레이아웃 그룹을 한 줄로 Item을 배치할 수 있다.
composition instead of subclassing
Subclassing을 하지 않아도 된다. (Concrete type)
추론 가능한 레이아웃으로 구성할 수 있기 때문에 매우 단순하다.
Compositional Layout Code 및 개념
Core Concepts
Untitled Type(유형)에 대해 자연스러운 Flow가 존재한다.
5가지 유형이 존재한다. (Item, Group, Section, Layout)
Untitled
Layout Types
Size
모든 것들은 명백한 사이즈를 가지고 있다.
사이즈를 쉽게 추론할 수 있는 방법 (각 Type이 얼마나 큰지 확인)
Size = Width + Height dimension
class NSCollectionLayoutSize { init(widthDimension: NSCollectionLayoutDimension, heightDimension: NSCollectionLayoutDimension) }
NSCollectionLayoutDimension
축과 무관한 방법으로, 폭과 높이, 차원에 대한 정보만을 이용해서 축의 크기를 설명한다.
이때, 폭과 높이의 경우, NSCollectionLayoutDimension이라는 새로운 유형으로 정의한다.
NSCollectionLayoutDimension의 4가지 유형
// 축의 크기를 나타내는 "축 독립적 방법" class NSCollectionLayoutDimension { class func fractionalWidth(_ fractionalWidth: CGFloat) -> Self class func fractionalHeight(_ fractionalHeight: CGFloat) -> Self class func absolute(_ absoluteDimension: CGFloat) -> Self class func estimated(_ estimatedDimension: CGFloat) -> Self }
특정 Item의 width = Container 폭의 50%를 차지한다.
Untitled Item의 Height = Container 폭의 30% 차지
Untitled 특정 종횡비를 갖도록 정의 (Container의 25%씩 aspect ratio)
Untitled 정확한 치수를 갖도록 정의 (point based value)
스크린샷 2023-09-26 오후 12.43.37.png
Item
기존의 Cell의 개념과 동일
class NSCollectionLayoutItem { convenience init(layoutSize: NSCollectionLayoutSize) var contentInsets: NSDirectionalEdgeInsets }
Group
Untitled Section (
NScollectionLayoutSection
)CollectionView의 단면을 기준으로 한 Layou의 정의
Section에 몇 개의 항목이 있는지에 대해
DataSource
에 직접 매핑되는 개체Initializer가 Group을 허용한다.
class NSCollectionLayoutSection { convenience init(layoutGroup: NSCollectionLayoutGroup) var contentInsets: NSDirectionalEdgeInsets }
Layout
최상위 Layout class
iOS, tvOS의 경우, UICollectionViewCompositionalLayout 사용
MacOS의 경우, NSViewCompositionalLayout 사용
플랫폼과 상관 없이, 모든 정의가 동일하다.
class UICollectionViewCompositionalLayout: UIcollectionViewLayout { init(section: NSCollectionViewSection) init(sectionProvider: @escaping SectionProvider) }
Last updated