@@DataSource protocol 채택 하던게
엊그제 같은데...
벌써 이렇게 컸다니!!! 🍼
안녕하세요. 오딘(Odin)입니다.
여러분 iOS개발 하시면서 CollectionVIew 많이들 사용하고 계시죠?? :)
저도 많이 사용하고는 있지만
cell animation의 끊김, Cell 재사용 문제 등 아쉬운 점들이 많이 있었습니다.
그런데 여러분...!!
iPhone 사용 유저의 96%가 iOS +14 이상을 사용하고 있답니다!!
그렇다는 뜻은!!
iOS +13이상부터 사용이 가능한 DiffableDataSource를 사용해서
TableView, CollectionView를 만들어도 문제가 되지 않는다는거겠죠~!! 🎉🎉
이왕 이렇게 된 김에
CollectionView의 역사에 대해서 간단하게 집어가면서 정리해 보려고 합니다~!!
(TableView는 점차 역사속으로 사라진다고 하니 패스으~)
아직 Diffable 동작이 어떻게 되는지 궁금하거나,
2024년 미래...👩🚀 DataSource와 Layout이 무엇인지 모르는 사람이라면
한번 읽어보면서 "이렇게 변하게 된거구나" 를 알았으면 좋겠습니다~!
그러면 우리 같이 공부해볼까요~?!
CollectionView의 시작
CollectionVIew의 등장
iOS +6에 처음 등장
'데이터 항목의 정렬된 컬렉션을 관리하고 사용자 지정 가능한 레이아웃을 사용하여 표시하는 개체' 입니다.
-> 이런 식으로 만들 수 있도록 도와주는 툴이라고 생각하시면 됩니다!!
CollectionView를 구성하는 중요한 부분들이 있는데요!!
데이터를 넣기 위한 UICollectionVIewDataSource,
Layout을 그리기 위한 UICollectionViewLayout,
화면에 보여주기 위한 UICollectionViewCell 이렇게 구분 할 수 있습니다.
이것들을 무엇이(Data), 어디에(Layout), 보여지는지(presentation)에 대한 관점으로 살펴볼 때
무엇(Data) - DataSource에서 Cell을 생성
어디에(Layout) - Layout에서 Attributes 생성
보여지는지(presentation) - CollectionView에서 Reuse해서 배치
이런 흐름으로 흘러간다고 볼 수 있습니다~!!
그래서 세 개 중 한 개 라도 문제가 생긴다면 error & 오작동이 발생하게 됩니다.
예를 들어 보자면
CollectionView를 그리기 위해서는 DataSource 프로토콜을 무조건 채택 해야 된다던지
CollectionView를 생성할 때 collectionViewLayout을 생성해주지 않았다던지
Scroll 시 재사용 문제로 인해 CheckBox가 안눌렀는데도 눌림 표시가 되어 있다던지
(갑자기 옛날 생각에 눈물이 나네요...😭)
그리고 CollectionView 생성 코드를 예제를 살펴보면
이처럼 간단하게 구성이 되어 있어 쉽고 빠르게 작성이 가능하고, 유연한 구조라고 할 수 있습니다~!
-> 그러나 CollectionView를 사용하여 그리다보면 문제점이 나타납니다.
CollectionVIew의 문제점
첫번째 - ReloadData()
간단하게 예를 들어보겠습니다.
웹 서비스 요청을 받은 Controller가 UI를 변경해달라는 요청을 하는 작업입니다.
- error -
다음과 같은 error가 발생합니다...!! ㅠㅜㅠ
그 이유는 데이터 변경시점에 ReloadData() 처리를 안해줘서 입니다.
왜 ReloadData()를 처리해주어야만 error가 발생하지 않을까요??
DataSource에 데이터를 넣어 Cell을 구성하는 부분을 살펴보면
Documentation에 적혀있는 내용과 해당 주석을 해석해보면
'DataSource에서 생성한 Cell이 CollectionView내에 들어 있는지 확인하는 작업이 거쳐지게 된다'
라고 이해할 수 있겠네요!!
즉,
이러한 로직이 거쳐지게 되면서 어떤 데이터(Controller, UI가 각각 데이터를 들고 있음)가 참인지 알기 어려워
Reload에 대한 error가 발생한다고 볼 수 있습니다!!!
그렇기 때문에 DataSource에 Data정보가 변경이 된다면 reloadData()를 통해
새로운 Data에 알맞는 sections와 rows를 CollectionView에 다시 그려줘야 하는 것입니다.
apple에서도 해당 방식을 괜찮다고는 합니다만,
이렇게 reloadData()를 하게 된다면 Animation이 적용되지 않아 뚝뚝 끊기는 모습이 보이게 됩니다.
두번째 - Cell reuse issue
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) // return ==> UICollectionViewCell
우리는 CollectionView를 만들 때 dequeueReusableCell 함수를 활용하여 재사용 cell 인스턴스 변수를 만들고
cell 내부에 필요한 데이터를 넣은 뒤 CollectionView에 넘겨주게 됩니다.
여기서 문제점을 찾으셨나요??
네!! 바로 재사용이 가능하도록 만들어진 cell에 직접 데이터를 넣어주는 것입니다.
위에서 보시는거와 같이 Cell은 Class로 reference type입니다.
그리고 우리는 cell 내부 생성 해두었던 변수에 값을 바로 넣어주는데요!!
이때, cell을 재사용하여 사용한다면 값은 변경될지 몰라도 변경된 UI는 원래 상태로 돌아가지 못한 채 나타나게 되는 것입니다.
이러한 문제점들을 해결하기 위해 우리 apple은 새로운 방식을 선보였습니다.
그것은 바로...!!
DiffableDataSource 의 등장
DiffableDataSource
iOS +13
새롭게 등장한 CollectionView를 구성하는 중요한 부분들은 다음과 같습니다!!
Diffable Data Source, Compositional Layout 이 새롭게 나타났네요!?
Layout은 화면을 그리는 용도이므로 Diffalbe data Source에 대해서 살펴봅시다.
Diffable Data Source
Diffable Data Source에는 Crash나 번거로움, 복잡성, 처리하고 싶지 않은 모든 것들이 없에고,
apply라는 단일 메소드가 있습니다.
그리고 문제점으로 ReloadData()을 이야기 드렸었는데요.
어떤 데이터가 참인지 알기 어려웠던 문제점을 해결하기 위해 참인 데이터를 한 개만 두고 처리 하기로 했습니다!!
SnapShot 도입
SnapShot은 한가지 참인 데이터를 관리하는 객체로 IndexPath가 아니라 이 Unique identifiers로 업데이트 하고
Unique identifiers 는 Hash value를 사용하여 판단합니다.
그래서 apply시에 각 hash value를 비교하여 추가 or 삭제된 부분을 인지하게 됩니다.
Cell Configuration
iOS +14
이전에 collectionView의 문제점 중에 하나로 Cell Reuse Issue 를 이야기 했었는데요!!
이 문제를 어떻게 해결했는지 같이 한번 확인해 보겠습니다!!
새롭게 등장한 CellRegist 방식입니다.
typealias CellRegistration = UICollectionView.CellRegistration<CustomCell, Item>
// cell 만드는 Code
let exampleDiffableCell = CellRegistration { cell, indexPath, item in
cell.configure(with: item) // cell에 값 넣기
}
// DataSource에 넣어주기
dataSource = DataSource(collectionView: collectionView, cellProvider: { collectionView, indexPath, item in
let cell = collectionView.dequeueConfiguredReusableCell(using: exampleDiffableCell, for: indexPath, item: item)
return cell
})
기존(iOS +6) cell을 만들 때
custom한 cell을 dequeueReusableCell 을 사용해서 인스턴스 변수를 바로 만든 후 바로 return 해 주었는데
dataSource 부분을 보면
CellRegistration을 통해 cell을 생성하고 dequeueConfiguredReusableCell에 넣어주는 모습을 볼 수 있습니다.
오호... CellRegistration을 한번 살펴 봐야겠군요!!
Struct!! 즉, Value Type로 만들어져 있네요!!
value Type 장점
- 설정할 때 당시의 값에만 영향을 받고 그 이후 configuration을 cell에 적용하지 전까지는 어떤 영향도 받지 않게 됩니다.
- 셀을 처음 구성할 때 뿐만 아니라 업데이트하려는 경우에도 적용되는데, configuration을 적용할 때는 이전 configuration이 어땠는지에 대해서 생각할 필요가 없습니다.
+ 추가 (UIListContentConfiguration)
후우....이렇게 CollectionView의 변화 과정에 대해서 정리해 보았는데요!!
아직 부족한 부분은 추가해서 정리해 두도록 하겠습니다!!ㅎㅎ
참조
WWDC 20
- Advances in UI Data Sources https://developer.apple.com/videos/play/wwdc2019/220/
- Modern cell configuration https://developer.apple.com/videos/play/wwdc2020/10027
Documentation
- UICollectionViewDataSource https://developer.apple.com/documentation/uikit/uicollectionviewdatasource/1618029-collectionview
'iOS > WWDC' 카테고리의 다른 글
[WWDC] SheetPresentationController 만들기 (0) | 2022.07.27 |
---|