🍎 iOS/iOS 기본 & UIKit

[iOS/UIKit] UITableView, UICollectionView 다시 살펴보기

dev_zoe 2023. 5. 22. 19:33
반응형

안녕하세요, 오늘은 항상 프로젝트에서 써왔지만 !!제대로!! 원리와 몰랐던 개념을 다시 정리해보고자 UITableView와 UICollectionView를 뜯어보고자 합니다.

 

1. UITableView

https://developer.apple.com/documentation/uikit/uitableview

 

UITableView | Apple Developer Documentation

A view that presents data using rows in a single column.

developer.apple.com

- 하나의 컬럼을 사용하여 여러가지 행 데이터들을 보여주는 뷰이다.  -> 세로 스크롤만 가능하다는 점을 알 수 있음

- 새삼스럽게 다시 알게된 사실이지만 UITableView는 UIScrollView를 상속하고 있다!

- 연관된 데이터를 하나의 "섹션"이라는 그룹으로 묶을 수 있다.

- 테이블뷰에 추가적인 정보를 나타내기 위해 헤더 혹은 푸터를 붙일 수 있다.

 

- 테이블뷰는 기본 style이 3가지로 구분되는데, 디폴트는 plain이며 각 스타일 별로 아래와같이 생겼다.

 

https://ios-development.tistory.com/538

 

[iOS - swift] tableView 스타일) Plain vs Grouped vs Inset Grouped

TableView의 3가지 style section의 개념 = header + rows + footer grouped는 header와 footer의 간격을 늘려주는 것 inset grouped는 rows들의 bounds가 둥근 모형으로되고 row양 옆에 inset이 들어가는 것 plain grouped inset grou

ios-development.tistory.com

 

2. UITableView 구현

1) 테이블뷰를 가지고 있는 뷰 컨트롤러는 UITableViewDataSoruce는 필수적으로, UITableViewDelegate는 필요에 따라 상속해야한다.

final class HomeViewController: UIViewController {
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        retrospectListTableView.delegate = self
        retrospectListTableView.dataSource = self

 

*UITableViewDataSource 주요 기능

https://developer.apple.com/documentation/uikit/uitableviewdatasource

 

UITableViewDataSource | Apple Developer Documentation

The methods that an object adopts to manage data and provide cells for a table view.

developer.apple.com

- 테이블뷰를 통해 보여줄 테이블의 섹션과 row값의 개수 지정 -> 해당 개수만큼의 셀을 생성하는 것이 아니라, 기존 셀을 재사용함 (필수)

- 각 행에 해당하는 UITableViewCell 지정 (필수)

- 헤더/푸터에 해당하는 title (기본 형식을 사용할 경우) 지정

 

* UITableViewDelegate 주요 기능

https://developer.apple.com/documentation/uikit/uitableviewdelegate

 

UITableViewDelegate | Apple Developer Documentation

Methods for managing selections, configuring section headers and footers, deleting and reordering cells, and performing other actions in a table view.

developer.apple.com

- 커스텀 헤더 / 푸터 커스텀 뷰 지정

- row, header, footer의 높이 사용자가 원하는 값으로 지정

- row 값을 클릭 할 때 어떤 동작을 할것인지 지정

- row를 스와이프하거나 편집할 때의 동작 정의

 

2) row 데이터를 채워나갈 데이터 구조를 struct로 정의하고, UITableView에 띄워줄 struct 인스턴스 리스트 준비

struct Friend{
    let name: String
    let address: String
}

let friendsList = [Friend(name: "yuri", address: "서울"), .... Friend(name: "sugil", address: "양산")]

 

3) 보여줄 Cell을 UITableView에 등록 (UITableview.register)

    private let cellID = "HomeLookAroundCollectionViewCell"

	override func viewDidLoad() {
    
		lookAroundCollectionView.register(UINib(nibName: cellID, bundle: nil), forCellWithReuseIdentifier: "lookaroundCell")
    }

* forCellWithReuseIdentifier는 무엇이고, 이미 앞에 셀 이름을 찾아서 등록하는데 왜 따로 구분하는 것일까?

- cell은 데이터가 1000개 10000개 있을 경우에 모든 cell을 다 불러오는 것이 아니라, 미리 화면에 보여줄 개수 정도만큼만 cell을 만들어두고 이를 스크롤을 내리고 올라올 때마다 미리 만들어둔 cell을 재사용하게 된다.

- 이 때 테이블뷰는 기존 셀을 재사용해야하므로, Cell의 이름과 identifier를 비교하게 되며 이 2개가 서로 같은 셀을 가리키는 경우에 정상적으로 셀 등록이 완료된다.

 

4) UITableViewDataSource의 delegate pattern을 통해 위임 받은 필수로 구현해야하는 메소드 구현

extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        friends.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: HomeRetrospectTableViewCell.id) as? HomeRetrospectTableViewCell else { return .init() }

		/*
        셀 어떤 형태로 보여줄것인지에 대한 UI 구성 코드
        */
        
        return cell
    }

 

- 위에서 register를 통해 등록한 셀과 dequeueReusableCell로 등록한 셀과 서로 일치해야만 정상적으로 테이블뷰를 보여주게 된다.

 

3. UICollectionView 이란?, UITableView와의 차이점

https://developer.apple.com/documentation/uikit/uicollectionview

 

UICollectionView | Apple Developer Documentation

An object that manages an ordered collection of data items and presents them using customizable layouts.

developer.apple.com

- 정렬된 데이터의 집합을 커스텀한 레이아웃으로 보여주는 뷰 (세로 스크롤만 가능한 것이 아니라, 사용자가 커스텀하여 데이터의 집합을 보여줄 수 있음)

- UICollectionViewLayout : 컬렉션뷰에서 셀의 정렬과 위치를 정의하는 레이아웃

 

✅ UITableView와 구현 방식이나 원리는 거의 유사하나, UITableView와의 가장 큰 차이는

"UITableView는 세로 스크롤 형태로만 구현이 가능하나, UICollectionView는 사용자가 정의한 레이아웃에 따라 데이터 집합 표현이 가능하다."

 

💡 그렇다면 UICollectionView는 레이아웃과 셀의 형태, 크기를 어떻게 지정하는가?

collectionView는 반드시 초기화할 때 CollectionViewLayout을 매개변수로 넣어서 지정해주어야 한다!

이게 없으면 UICollectionView는 어떤 형식으로 보여줘야할지 모르기 때문에 반드시 layout을 지정해야한다. (Must not be nil)

어 그런데 왜 UICollectionViewLayout이 아니라 UICollectionViewFlowLayout 인걸까?

UICollectionViewLayout은 추상클래스이고, 이를 구체적으로 구현한 클래스가 바로 UICollectionViewFlowLayout이다.

UICollectionViewFlowLayout만 와야한다!는 아니고 여러 종류가 있다. (보통 막 특이한 경우 아닌이상 이 레이아웃을 쓰기는 한다.)

 

https://demian-develop.tistory.com/21

 

iOS) UICollectionView custom layout에 대한 고찰- 1 (UICollectionViewFlowLayout, UICollectionViewLayout)

Collection View에서 복잡한 레이아웃을 다루기 위해선 Custom Layout을 적용시켜야 합니다. 오늘은 Custom Layout을 탐구해보려 합니다. 데이터 레이어와 프레젠테이션 레이어가 분리되어있고 레이아웃으

demian-develop.tistory.com

이 블로그가 설명이 너무 잘 되어있어서 시리즈를 쭉 읽어보았다.

https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/layouts/customizing_collection_view_layouts

 

Customizing Collection View Layouts | Apple Developer Documentation

Customize a view layout by changing the size of cells in the flow or implementing a mosaic style.

developer.apple.com

공식문서에도 CollectionView 레이아웃을 커스텀하는 것에 대한 코드를 친절하게 올려두었더라

단순한 그리드 형식이라면 UICollectionViewFlowLayout을 사용해라! 더 복잡한 레이아웃을 구현하고자 한다면, UICollectionViewLayout을 상속한 다른 클래스 레이아웃을 구현해라! 라고 나와있다.

flowlayout에서 사실상 대부분의 컬렉션뷰를 기본적인 기능을 이용하는 것만으로 구현이 가능하기 때문에, 보통은 flow layout을 통해 컬렉션뷰 레이아웃을 사용한다.

- 스크롤 방향을 세로 뿐만 아니라 가로 방향도 지원하며, 셀 간 줄 간격 / 셀 간 간격 / 셀의 사이즈 등을 조정하여 컬렉션뷰를 구현할 수 있다.

- UICollectionViewFlowLayout을 통해 컬렉션뷰 레이아웃을 구성하고자 한다면, UICollectionViewDelegateFlowLayout 프로토콜을 구현하면 된다.

 

반응형