안녕하세요, 오늘은 항상 프로젝트에서 써왔지만 !!제대로!! 원리와 몰랐던 개념을 다시 정리해보고자 UITableView와 UICollectionView를 뜯어보고자 합니다.
1. UITableView
https://developer.apple.com/documentation/uikit/uitableview
- 하나의 컬럼을 사용하여 여러가지 행 데이터들을 보여주는 뷰이다. -> 세로 스크롤만 가능하다는 점을 알 수 있음
- 새삼스럽게 다시 알게된 사실이지만 UITableView는 UIScrollView를 상속하고 있다!
- 연관된 데이터를 하나의 "섹션"이라는 그룹으로 묶을 수 있다.
- 테이블뷰에 추가적인 정보를 나타내기 위해 헤더 혹은 푸터를 붙일 수 있다.
- 테이블뷰는 기본 style이 3가지로 구분되는데, 디폴트는 plain이며 각 스타일 별로 아래와같이 생겼다.
https://ios-development.tistory.com/538
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
- 테이블뷰를 통해 보여줄 테이블의 섹션과 row값의 개수 지정 -> 해당 개수만큼의 셀을 생성하는 것이 아니라, 기존 셀을 재사용함 (필수)
- 각 행에 해당하는 UITableViewCell 지정 (필수)
- 헤더/푸터에 해당하는 title (기본 형식을 사용할 경우) 지정
* UITableViewDelegate 주요 기능
https://developer.apple.com/documentation/uikit/uitableviewdelegate
- 커스텀 헤더 / 푸터 커스텀 뷰 지정
- 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
- 정렬된 데이터의 집합을 커스텀한 레이아웃으로 보여주는 뷰 (세로 스크롤만 가능한 것이 아니라, 사용자가 커스텀하여 데이터의 집합을 보여줄 수 있음)
- 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
이 블로그가 설명이 너무 잘 되어있어서 시리즈를 쭉 읽어보았다.
공식문서에도 CollectionView 레이아웃을 커스텀하는 것에 대한 코드를 친절하게 올려두었더라
단순한 그리드 형식이라면 UICollectionViewFlowLayout을 사용해라! 더 복잡한 레이아웃을 구현하고자 한다면, UICollectionViewLayout을 상속한 다른 클래스 레이아웃을 구현해라! 라고 나와있다.
flowlayout에서 사실상 대부분의 컬렉션뷰를 기본적인 기능을 이용하는 것만으로 구현이 가능하기 때문에, 보통은 flow layout을 통해 컬렉션뷰 레이아웃을 사용한다.
- 스크롤 방향을 세로 뿐만 아니라 가로 방향도 지원하며, 셀 간 줄 간격 / 셀 간 간격 / 셀의 사이즈 등을 조정하여 컬렉션뷰를 구현할 수 있다.
- UICollectionViewFlowLayout을 통해 컬렉션뷰 레이아웃을 구성하고자 한다면, UICollectionViewDelegateFlowLayout 프로토콜을 구현하면 된다.
'🍎 iOS > iOS 기본 & UIKit' 카테고리의 다른 글
[iOS/Swift] Notification Center (0) | 2023.04.20 |
---|---|
[iOS] 뷰 컨트롤러 생명주기 / 앱 생명주기 (0) | 2021.09.09 |
[iOS] Swift에서 데이터를 전달하는 방법 (0) | 2021.09.07 |
[iOS] AppDelegate, SceneDelegate (+UIWindow, UIScene, UIWindowScene) (0) | 2021.09.07 |
[iOS] 프로젝트 속성 조사 (PROJECT, TARGETS) (0) | 2021.08.31 |