[iOS] UITableView & UICollectionView
앱 내에서 여러 컨텐츠를 보여주기 위해서는 리스트 형태로 출력하는것이 매우 효과적입니다.
iOS 에서는 UITableView 와 UICollectionView 를 이용해 리스트 형태를 구현할 수 있는데, 오늘은 이 둘의 특징에 대해 알아보겠습니다.
UITableView
- 단일 Column 을 가지고 Row 마다 데이터를 표시하는 View
- UIScrollView 를 상속받으며 수직 스크롤만 가능
- Section 을 이용해 Row 들을 그룹화할 수 있음
- 각 Section 은 Header 와 Footer 를 옵션으로 가질 수 있음
TableView 는 계층구조의 데이터가 있는 앱에서 일반적으로 사용됩니다.
TableView 와 Navigation Controller 를 이용하면 계층간 탐색을 다양하게 구현할 수 있습니다.
대표적인 예로는 iOS 의 연락처 앱과 설정 앱이 있습니다.
UITableViewCell
UITableViewCell 은 TableView 의 Row 를 관리하는 cell 입니다.
Cell 을 이용하여 주로 사용자 지정 컨텐츠를 구성하고 표시하기도 하지만, UITableViewCell 은 테이블 관련 동작을 지원하기 위해 몇 가지 기능을 제공합니다.
- Cell 에 색상을 적용합니다.
- 세부 정보와 같은 Accessory View 추가
- Cell 을 편집 가능한 상태로 전환
- Cell 내용을 들여쓰기하여 시각적인 계층구조 구성
Storyboard 에서 Cell 의 내용 및 레이아웃을 구성할 수 있습니다.
이 때 identifier 를 지정해 테이블이 Cell 을 재사용할 수 있도록 하고, UITableViewCell 을 상속받는 Class 를 생성해 Cell 을 커스터마이징 할 수 있습니다.
UICollectionView
- 여러 개의 Column 을 나타낼 수 있으며, UITableView 보다 더 자유롭게 Cell 구성 가능
- UIScrollView 를 상속받으며 수직, 수평 스크롤 모두 가능
UICollectionView 는 Header 나 Footer 를 나타낼 수 있는 Supplementary View, 그리고 컨텐츠 내용을 표시할 수 있는 Cell 로 표현됩니다.
TableView 에서는 Cell 을 구성할때 항상 Row 에 맞춰 디자인해야 했지만, CollectionView 에서는 Row 와 Column 을 모두 직접 구성할 수 있습니다.
또한 Layout 객체를 가지고 있어 Cell 을 더 자유롭게 커스터마이징 할 수 있습니다. 하지만 기본 제공 스타일을 가지고 있지는 않습니다.
Delegate Pattern
UITableView 와 UICollectionView 는 Delegate Pattern 을 기반으로 동작합니다.
각각에서 제공하는 Delegate 와 DataSource 프로토콜을 채택하여 구현하는데, 이 때 프로토콜에서 필수적으로 구현해야하는 메소드들 중에서는 Cell 을 구성하는 메소드와 아이템의 개수를 나타내는 메소드 등이 있습니다.
이 중 Cell 을 구성하는 메소드 cellForRowAt, cellForItemAt 에서는 공통적으로 dequeueReusableCell() 이라는 메소드를 사용합니다.
TableView 와 CollectionView 는 많은 데이터들을 화면에 효율적으로 나타내야하는 것이 목표이기 때문에 Cell 을 사용하는데, 이때 필요한 Cell 을 처음부터 모두 사용한다면 메모리 측면에서 비효율적이기 때문에 dequeueReusableCell() 이라는 메소드를 사용합니다.
Cell 이 스크롤 이벤트로 인해 화면 밖으로 사라진다면 더 이상 사용되지 않는 Cell 들은 Queue 에 들어갑니다. 그리고 다시 Cell 이 렌더링 되어야하는 위치로 삽입되어 재사용됩니다.
처음 화면이 켜져서 재사용될 수 있는 Cell 이 없을 시에는 스토리보드에서 프로토타입을 복사해서 생성합니다.
Diffable DataSource
iOS 13 부터는 TableView 와 CollectionView 모두에서 DiffableDataSource 라는 것을 지원하는데, 이는 제네릭 클래스로 DataSource 프로토콜을 채택하고 있습니다.
UICollectionView 를 예로 들어보겠습니다.
크게 Section 과 Item 을 요구하는데 이 때 두 타입은 모두 Hashable 프로토콜을 준수해야합니다.
그렇다면 왜 DiffableDataSource 라는것이 생긴걸까요?
원래 하던대로 CollectionView 나 TableView 를 사용한다면 해당 컴포넌트를 담고있는 ViewController 자체가 DataSource 와 Delegate 프로토콜을 채택했습니다.
외부에서 데이터가 변경된다거나 어떤 response 가 주어질때 Controller 는 해당 입력을 처리하고 UI 에 출력하는데, 이 때 저희는 reloadData() 메소드를 사용합니다.
하지만 이는 좋지 않은 사용자 경험을 제공하며, 데이터가 변경되는 시점마다 reloadData() 를 호출해야 한다는 번거로움이 있습니다.
그래서 Snapshot 과 apply() 메소드를 이용합니다. Snapshot 은 UI 의 상태를 담고 있는데 이를 DataSource 에 apply() 메소드를 이용해 적용하게 된다면 데이터가 변경될때마다 새로운 Snapshot 을 적용시켜줄 수 있습니다.
UICollectionViewCompositionalLayout
CollectionView 에서는 더 유연하고 다양한 레이아웃을 표현하기 위해 CompositionalLayout 을 사용할 수 있습니다.
기존에 존재하던 Section 과 Item 의 중간계층인 Group 이 추가되었고, 이를 이용해 더 다양한 레이아웃을 구성할 수 있습니다.
다음 링크의 프로젝트를 살펴보시면 CollectionView 를 이용한 많은 예제를 확인하실 수 있습니다.
마무리
오늘은 UITableView 와 UICollectionView 에 대해 알아보았습니다.
정리하자면 둘의 공통점은 아래와 같이 정리할 수 있습니다.
- UIScrollView 를 상속받아 많은 데이터를 리스트 형태로 표현
- Cell 을 기반으로 여러 데이터를 표현
- Section 을 나눌 수 있으며 각 Section 은 Header 와 Footer 를 가질 수 있음
- Delegate 와 DataSource 를 채택하여 기능을 구현하는 Delegate Pattern 으로 동작
차이점은 아래와 같이 정리할 수 있습니다.
- TableView 는 단일 Column, CollectionView 는 여러 Column 으로 2차원 형태 표현 가능
- TableView 는 수직 스크롤만, CollectionView 는 수직 수평 스크롤 가능
- TableView 는 기본 스타일이 있지만, CollectionView 는 직접 커스터마이징 해야함 (더 자유롭게 표현 가능)
참고 링크
Apple Developer Docs
https://developer.apple.com/documentation/uikit/uitableview
https://developer.apple.com/documentation/uikit/uitableviewcell
https://developer.apple.com/documentation/uikit/uicollectionview
https://developer.apple.com/documentation/uikit/uicollectionviewcell
https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource
https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayout
https://velog.io/@leeyoungwoozz/iOS-UICollectionView-vs-UITableView
https://jayb-log.tistory.com/229
https://nareunhagae.tistory.com/19
https://www.raywenderlich.com/5436806-modern-collection-views-with-compositional-layouts
https://zeddios.tistory.com/1197
'iOS 개발 > iOS' 카테고리의 다른 글
[iOS] Delegate Pattern (0) | 2022.07.06 |
---|---|
[iOS] UINavigationController (0) | 2022.06.30 |
[iOS] 앱 생명주기 (App LifeCycle) (0) | 2022.06.24 |
[iOS] Frame & Bounds (0) | 2022.06.17 |
[iOS] ViewController LifeCycle (생명주기) (0) | 2022.06.16 |