반응형
UITableView, UICollectionView
공통점
- TableView와 CollectionView는 iOS 앱에서 데이터를 목록 형태로 표시하는 데 사용되는 UI 컴포넌트로 둘 다 스크롤 가능한 콘텐츠를 표시
차이점
특징 UITableView UICollectionView
방향성 | 기본적으로 단일 열(세로) 또는 단일 행(가로)의 선형 목록 | 여러 열/행, 그리드, 원형 등 다양한 형태로 데이터 표현 가능 |
복잡성 | 단순한 목록 표시 및 섹션 구분에 적합 | 복잡한 레이아웃과 다양한 시각적 표현에 적합 |
레이아웃 | 고정된 선형 레이아웃 | UICollectionViewLayout을 통해 매우 유연한 레이아웃 제공 |
용도 | 설정 화면, 이메일 목록, 뉴스 피드 등 | 갤러리, 앱 스토어, 소셜 미디어 피드 등 |
헤더/푸터 | 섹션 헤더/푸터 지원 | 섹션 헤더/푸터 및 보조 뷰(Supplementary View) 지원 |
테이블 뷰와 컬렉션 뷰에서 셀을 재사용하는 이유와 방법
셀 재사용 이유
- 테이블 뷰와 컬렉션 뷰는 화면에 동시에 보이는 셀의 개수가 제한적임 → 사용자가 스크롤을 하면서 새로운 셀이 화면에 나타나야 할 때, 매번 새로운 셀 객체를 생성하면 메모리 사용량이 급증하고 성능이 저하될 수 있기에 셀을 재사용
- 메모리 효율성, 성능 향상
셀 재사용 방법
- 둘 다 dequeueReusableCell(withIdentifier:for:) 메서드를 사용하여 셀을 재사용 → 특정 식별자를 가진 재사용 가능한 셀을 큐에서 가져옴
- 셀 등록
- register(_:forCellReuseIdentifier:) 메서드를 사용하여 셀 클래스를 등록
**// 테이블 뷰** tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "MyCell") **// 컬렉션 뷰** collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
- 셀 재사용 및 구성
- dataSource 메서드 내에서 셀을 재사용하고 데이터 설정
**// 테이블 뷰 (UITableViewDataSource)** func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as? MyTableViewCell else { fatalError("Unable to dequeue MyTableViewCell") } // 셀에 데이터 설정 cell.configure(with: data[indexPath.row]) return cell } **// 컬렉션 뷰 (UICollectionViewDataSource)** func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as? MyCollectionViewCell else { fatalError("Unable to dequeue MyCollectionViewCell") } // 셀에 데이터 설정 cell.configure(with: data[indexPath.item]) return cell }
테이블 뷰와 컬렉션 뷰의 데이터 소스(Data Source)와 델리게이트(Delegate)의 역할
데이터 소스(Data Source)
- 테이블 뷰 또는 컬렉션 뷰에 표시할 데이터를 제공하고, 각 섹션의 행(item) 수, 각 셀에 표시할 데이터 등을 결정
- 즉, 뷰가 자신의 내용을 구성하는 데 필요한 모든 정보를 제공하는 책임을 가짐
- 주요 메서드
- numberOfSections(in:)
- 섹션의 수를 반환
- tableView(_:numberOfRowsInSection:) / collectionView(_:numberOfItemsInSection:)
- 각 섹션의 행/아이템 수를 반환
- tableView(_:cellForRowAt:) / collectionView(_:cellForItemAt:)
- 특정 **indexPath**에 해당하는 셀 객체를 반환하고 데이터를 설정
- tableView(_:titleForHeaderInSection:) / collectionView(_:viewForSupplementaryElementOfKind:at:)
- 섹션 헤더/푸터에 대한 정보를 제공합니다.
- numberOfSections(in:)
델리게이트(Delegate)
- 테이블 뷰 또는 컬렉션 뷰에서 발생하는 이벤트에 응답하고, 셀의 높이, 셀 선택 시의 동작, 스크롤 동작 등 뷰의 동작과 외형에 영향을 주는 다양한 사용자 인터랙션 및 시각적 속성을 제어
- 즉, 사용자 액션에 대한 응답을 처리하고 뷰의 동작을 커스터마이징하는 책임을 가짐
- 주요 메서드
- tableView(_:didSelectRowAt:) / collectionView(_:didSelectItemAt:)
- 셀이 선택되었을 때 호출
- tableView(_:heightForRowAt:)
- 각 행의 높이를 지정합니다.
- scrollViewDidScroll(_:)
- 스크롤 뷰가 스크롤될 때 호출 (두 뷰 모두 UIScrollViewDelegate를 상속받음)
- tableView(_:willDisplay:forRowAt:)
- 셀이 화면에 표시되기 직전에 호출
- tableView(_:didSelectRowAt:) / collectionView(_:didSelectItemAt:)
컬렉션 뷰에서 사용할 수 있는 레이아웃(Layout)의 종류와 특징
- UICollectionViewFlowLayout
- 그리드 기반의 선형 레이아웃
- 가장 일반적인 레이아웃으로, 아이템들이 일정한 크기로 배치되거나, 한 줄에 여러 개가 배치되는 그리드 형태에 적합
- 아이템 간의 최소 간격, 섹션 여백, 헤더/푸터 크기 등을 설정 가능
- UICollectionViewCompositionalLayout (iOS 13+)
- UICollectionViewFlowLayout의 복잡성을 해결하고, 복잡한 레이아웃을 선언적으로 쉽게 구성할 수 있도록 설계됨
- UICollectionViewFlowLayout만으로는 구현하기 어려웠던 다양한 형태의 그리드, 리스트, 섹션 레이아웃까지 유연하게 표현 가능
- 세 가지 주요 계층 구조
- Item
- 레이아웃의 가장 작은 단위
- 실제 데이터를 표시하는 셀에 해당
- NSCollectionLayoutItem을 통해 정의
- Group
- 하나 이상의 Item을 포함하는 그룹
- 수평, 수직, 사용자 정의 그룹을 만들 수 있음
- NSCollectionLayoutGroup을 통해 정의
-
- 하나 이상의 Group을 포함하는 섹션
- 헤더, 푸터, 백그라운드 등 추가 가능
- NSCollectionLayoutSection을 통해 정의Section
- Item
- UICollectionViewLayout
- 모든 컬렉션 뷰 레이아웃의 기본 클래스
- UICollectionViewFlowLayout이나 UICollectionViewCompositionalLayout으로 구현하기 어려운 매우 독특하고 사용자 정의된 레이아웃이 필요할 때 직접 서브클래싱하여 구현
- 필수 오버라이드 메서드
- prepare()
- 레이아웃 계산을 위한 초기 설정
- layoutAttributesForElements(in:)
- 주어진 사각형 범위 내의 모든 항목에 대한 레이아웃 속성 반환
- layoutAttributesForItem(at:)
- 특정 indexPath에 대한 항목의 레이아웃 속성 반환
- collectionViewContentSize
- 컬렉션 뷰의 콘텐츠 크기 반환
- prepare()
반응형
'DEV' 카테고리의 다른 글
[iOS/Swift] ReactorKit bind() 자동 호출 안되는 오류 (1) | 2025.06.20 |
---|---|
[iOS/Swift] iOS 앱에서 데이터를 영구적으로 저장하기 위해 사용할 수 있는 방법들(UserDefaults, Keychain, Plist, FileManager, SQLite, Core Data, Realm)의 특징과 각각의 장단점, 적합한 사용 사례 (2) | 2025.06.05 |
REST API와 iOS에서의 네트워크 요청 및 응답 처리 방법 (0) | 2025.05.15 |
[iOS/Swift] CollectionView, TableView 오류발생 (0) | 2025.04.09 |
[iOS/Swift] UIStackView(arrangedSubviews: [ ]) (0) | 2025.04.02 |