iOS) Diffable Data Source ์์๋ณด๊ธฐ
๐ทDiffable Data Source ๋?
- ๋จผ์
Diffable Data Source
๊ฐ ๋ฌด์์ธ์ง์ ๋ํด์ ๊ฐ๋จํ๊ฒ ์๊ณ ๋์ด๊ฐ๋ณด์!
TableView(๋๋ CollectionView)๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ UI๋ฅผ ์ ๋ฐ์ดํธ ํ๋ ์ญํ ์ ํ๋ค.
Data Source
์ ๋ฌ๋ฆฌ ๋ฐ์ดํฐ๊ฐ ๋ฌ๋ผ์ง ๋ถ๋ถ์ ์ถ์ ํ์ฌย ์์ฐ์ค๋ฝ๊ฒ UI๋ฅผ ์ ๋ฐ์ดํธํ๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก,
Diffable Data Source
์Data Source
์ ์ญํ ์ ๊ฐ๋ค. ๊ทธ๋ฌ๋,Diffable Data Source
๋ฅผ ์ฌ์ฉํ๋ฉด table view ๋ collection view ๋ฅผ ๊ฐ์ํํ๊ฒ ์ ๋ฐ์ดํธ๊ฐ ๊ฐ๋ฅํ๋ค.Data Source
๋ Protocol ์ด๋ค. ๋ฐ๋ฉด์Diffable Data Source
๋ Generic Class์ด๋ฉฐ, ํด๋น ํด๋์ค๊ฐData Source
๋ฅผ ์ฑํํ๊ณ ์๋ค.
WWDC
WWDC 2019 > Advances in UI Data Source ์์ ์๊ฐ๋์๊ณ , iOS 13 ๋ถํฐ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ WWDC 2021 > Make blazing fast lists and collection views ์์ diffable data source ์ ๋ํ ๊ฐ์ ์ฌํญ์ด ์๊ฐ๋์๋ค.
์๊ฐ๊ธ์ ์ดํด๋ณด๊ณ ์ ๋ฆฌํด๋ณด์๋ค.
๐ง๐ปโ๐ปย WWDC 2019
- UI Data Sources ๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ ๋น๊ต๋ฅผ ํตํด์ table view ์ collection view items ์ ์ ๋ฐ์ดํธ๋ฅผ ๊ฐ์ํํ ์ ์์ต๋๋ค.
- ๊ณ ํ์ง์ ์ ๋๋ฉ์ด์ ์ด ์๋์ผ๋ก ์ด๋ฃจ์ด์ง๊ณ , ์ถ๊ฐ์ ์ ์ฝ๋๊ฐ ํ์ํ์ง ์์ต๋๋ค!
- ๊ฐ์ ๋ data source ๋ฉ์ปค๋์ฆ์ ๋๊ธฐํ ๋ฒ๊ทธ, ์์ธ ๋ฐ ์ถฉ๋์ ์์ ํ ๋ฐฉ์งํฉ๋๋ค!
- UI ๋ฐ์ดํฐ ๋๊ธฐํ์ ์ฌ์ํ ๋ถ๋ถ ๋์ ์ฑ์ ๋์ ๋ฐ์ดํฐ์ ์ฝํ
์ธ ์ ์ง์คํ ์ ์๋๋ก
identifiers
์snapshots
๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ํ๋ data model ์ ๋ํด ์์๋ณด์ธ์.
๐ง๐ปโ๐ปย WWDC 2021
- ์ผ๊ด๋๊ฒ ๋ถ๋๋ฌ์ด scrolling list ๊ทธ๋ฆฌ๊ณ collection views: ์ ์ lifecycle ์ ํ์ํ๊ณ ํด๋น ์ง์์ ์ ์ฉํด์ ๊ฑฐ์น ์คํฌ๋กค ๋ฐ ๋๋ฝ๋ ํ๋ ์์ ์ ๊ฑฐํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ์ธ์.
- ๋ํ ์ต์ ํ๋ ์ด๋ฏธ์ง ๋ก๋ฉ ๋ฐ automatic cell prefetching ์ ํตํด์ ์ ๋ฐ์ ์ธ ์คํฌ๋กค ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ๋น์ฉ์ด ๋ง์ด๋๋ ์ฅ์ ๋ฅผ ํผํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋คโฆโฆ(์๋ต)
โ์ด์ ์ ์ฌ์ฉ๋ UITableView/CollectionViewDataSource ์ ์ญํ ์?
- section ๊ณผ row / item ์ ์๋ฅผ ์ ๊ณต
- ๊ฐ ํ์ ๋ํ ์ ์ ์ ๊ณต
- section ์ header ์ footer ์ ๊ณต
- ๋ฐ์ดํฐ ๋ณํ์ ๋ฐ์
๋ฑ๋ฑ ์ญํ ์ ํ๊ณ ์์์ด์! ํ์๋ก ๊ตฌํํด์ผํ ๋ฉ์๋๋ ์กด์ฌํ์์ฃ ! collection view ๋ก ์์๋ณด์๊ตฌ์ฌ
- collection view ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ํ๋กํ ์ฝ์ ๋๊ฐ์ง ๋ฉ์๋๋ฅผ ๋ฐ๋์ ๊ตฌํํด์ฃผ์ด์ผ ํ์ด์!
// MARK: UICollectionViewDataSource
// โ
๊ฐ section ์ ์์ดํ
๊ฐฏ์ ์ ๊ณต.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
// โ
๊ฐ ํ์ ๋ํ ์
์ ๊ณต.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? HomeCollectionViewCell else { return UICollectionViewCell() }
return cell
}
โWhy?
๊ทธ๋ผ ์? Diffable Data Source ๊ฐ ๋ฑ์ฅํ๊ฑธ๊น์?
WWDC 2019
์์ ์ ์ค๋ช
ํด์ฃผ๊ณ ์๋๋ฐ์. ๊ธฐ์กด Controller ์ UI ๊ด๊ณ๋ฅผ ์ดํด๋ณด์๊ตฌ์.
Controller ๊ฐ ์น์๋น์ค ์๋ต์ ๋ฐ๊ณ , ๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ์ฒ๋ฆฌํด์. ๊ทธ๋ฆฌ๊ณ UI ์๊ฒ ๋ฐ๋์๋ค๊ณ ์ ๋ฌํด์. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ์๋ฌ๋ฅผ ๋ง์ฃผํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ Diffalbe Data Source ๋ ๋ฐ๋ก ๋ค์ ์ํฉ์ ํด๊ฒฐํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค.
- ์น์
์๊ฐ ์๋ชป๋์ด ์ฑ์ด ์ข
๋ฃ๋๋ ๊ฒฝ์ฐ์์! ์์ ์๋ฌ๋ ๋ฐ์ดํฐ์ ๋ณ๊ฒฝ ์ํฉ์ ์๋์ผ๋ก ๋๊ธฐํํด์ผํจ์ ์๋ฏธํด์. ๋ฐ๋ผ์
reloadData
๋ฅผ ํตํด์ ๋๊ธฐํํด์ฃผ์ด์ผ ํด์.
โ๋ญ๊ฐ ๋ฌธ์ ์ฃ ?
๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ UI ์ DataSource ์ญํ ์ ํ๋ Controller ๊ฐ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ณํ๋ ์๊ธฐ๋ค๋ง์ ๋ฒ์ ์ธ truth ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ ๊ฒ์ ๋๋ค.(own version of the truth)
์ด truth ๊ฐ ์๋ก ๋ง์ง ์๊ฒ๋๋ฉด ์์ ๊ฐ์ ์๋ฌ๊ฐ ๋๋๊ฒ์ด์ฃ ! ์ด๋ฌํ ์ ๊ทผ๋ฐฉ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ์ต๋๋ค. centralize ๋ truth ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ ๋ค์ ๋์๊ฐ๋ณผ๊ฒ์!
WWDC ์์๋ reloadData
๋ฅผ ํตํ ๋๊ธฐํ๋ฅผ ๊ด์ฐฎ๋ค๊ณ ํด์. ๊ทธ๋ฌ๋ ๋ชจ๋๊ฐ ์๋ค์ํผ reloadData
๋ฅผ ํ๊ฒ ๋๋ฉด ์ ๋๋ฉ์ด์
์์ด ๋ํ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ(UX) ๋ฅผ ์ ํ์ํจ๋ค๊ณ ํด์. ๋์ Diffable Data Source
๋ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ ๋ถ๋ถ์ ๋ํด์ ์์ฐ์ค๋ฌ์ด ์
๋ฐ์ดํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋์ ์์์ ๊ทธ๋ ๊ฒ ๊ณ ํ์ง์ ์ ๋๋ฉ์ด์
, ์คํฌ๋กค ๊ฒฝํ ๊ฐ์ ์ ๋ํด์ ๊ฐ์กฐํ ๊ฒ์ด์ฃ .
- data source
์ถ์ฒ: https://velog.io/@ellyheetov/UI-Diffable-Data-Source
- diffable data source
์ถ์ฒ: https://velog.io/@ellyheetov/UI-Diffable-Data-Source
โ๊ทธ๋ ๋ค๋ฉด ๊ธฐ์กด์๋ ์์ฐ์ค๋ฌ์ด ์ ๋๋ฉ์ด์ ์ด ์์๋์?
- ๊ธฐ์กด์ ํน์ cell๋ง ๋ฐ๋๊ฒฝ์ฐ์ ์ฒ๋ฆฌ๋ ์๋์ ๊ฐ์ด ์ฒ๋ฆฌํ์ด์.
- ๋ฐฉ๋ฒ 1)
performBatchUpdates()
์ ํด๋ก์ ๋ธ๋ก์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์ ์ถ๊ฐ.(insert, delete, reload, move ์ฐ์ฐ์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ animate ํ๋ค.) - ๋ฐฉ๋ฒ 2)
beginUpdates()
์endupdates()
์ฌ์ด์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์ ์์ฑ.(์ผ๋ถ๋ถ๋ง์ ๋ณํ์ํค๋ ๋ฐฉ๋ฒ. ์ ๋๋ฉ์ด์ ๋ธ๋ก์ ๋ง๋ค ์ ์๋ค.)
- ๋ฐฉ๋ฒ 1)
โDiffable DataSource ์์๋?
- iOS 13+ ์์๋ apply()) ๋ฅผ ํตํด์ ์ ์์ ๋ค์ ์ฒ๋ฆฌ ๊ฐ๋ฅํด์!
โจย **apply(_:animatingDifferences:completion:)**
- snapshot ์ ๋ฐ์ดํฐ ์ํ๋ฅผ ๋ฐ์ํ๋๋ก UI ๋ฅผ ์ ๋ฐ์ดํธํ๊ณ , ์ ํ์ ์ผ๋ก UI ๋ณ๊ฒฝ์ฌํญ์ ์ ๋๋ฉ์ด์ ์ ์ ์ฉํ๊ณ completion handler ๋ฅผ ์คํํ๋ค.
Parameter
- snapshot: table / collection view ์์ ๋ฐ์ดํฐ์ ์ ์ํ๋ฅผ ๋ฐ์ํ๋ snapshot.
- animatingDifferences:
true
์ธ ๊ฒฝ์ฐ, ์์คํ ์ table / collection view ์ ๋ํ ์ ๋ฐ์ดํธ๋ฅผ ์ ๋๋ฉ์ด์ ์ผ๋ก ๋ง๋ ๋ค.false
์ธ ๊ฒฝ์ฐ, ์์คํ ์ ์ ๋ฐ์ดํธ๋ฅผ ์ ๋๋ฉ์ด์ ํ์ง ์๋๋ค. - completion: ์ ๋๋ฉ์ด์ ์ด ์๋ฃ๋๋ฉด ์คํํ ํด๋ก์ . ์์คํ ์ main queue ์์ ์ด ํด๋ก์ ๋ฅผ ํธ์ถํ๋ค.
โจย Snapshot
Snapshot
์ ๊ฐ๋จํ ๋งํด์ ํ์ฌ UI state ์ truth ์ ๋๋ค.- section ๊ณผ item ์ ๋ํด unique identifiers ๊ฐ ์์ต๋๋ค.
- IndexPath ๊ฐ ์๋๋ผ unique identifiers ๋ก ์ ๋ฐ์ดํธํ๊ฒ ๋ฉ๋๋ค.
โ๏ธ์์ ๋ฅผ ํตํด์ ์์๋ณด์๊ตฌ์!
- FOO,ย BAR,ย BIF ๋ก ๊ตฌ์ฑ๋ Cureent Snapshot ์ด ์กด์ฌํฉ๋๋ค.
- ๊ทธ ํ, Controller๊ฐ ๋ณ๊ฒฝ๋์๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค. ์ฆ, apply() ํ ์ ์๋ ์๋ก์ด
Snapshot
์ด ์๊ธด๊ฑฐ์ฃ .
๐ท์ฌ์ฉํด๋ณด์!
1๏ธโฃย UICollectionViewDiffalbeDataSource ์์๋ณด๊ธฐ
- Table View ๋ ๊ฑฐ์ ๋์ผํ๊ธฐ๋๋ฌธ์ UICollectionView ๋ก ์งํํ๊ฒ ์ต๋๋ค!
- ๊ฐ๋ฐ์๋ฌธ์๋ฅผ ์ดํด๋ด ์๋ค!
โจย UICollectionViewDiffableDataSource
๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ collection view ์ ๋ํ cells ์ ์ ๊ณตํ๋๋ฐ ์ฌ์ฉํ๋ ๊ฐ์ฒด์ ๋๋ค.
Declaration
@MainActorย classย UICollectionViewDiffableDataSource<SectionIdentifierType,ย ItemIdentifierType> :ย [NSObject](https://developer.apple.com/documentation/objectivec/nsobject)ย whereย SectionIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable),ย ItemIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable)
Overview
diffable data source ๊ฐ์ฒด๋ collection view ๊ฐ์ฒด์ ํจ๊ป ์๋ํ๋ ํน์ํ ์ ํ์ data source ์ ๋๋ค. ๋ฐ์ดํฐ์ UI ์ ๋ํ ์ ๋ฐ์ดํธ๋ฅผ ๊ฐ๋จํ๊ณ , ํจ์จ์ ์ธ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํ๋๋ฐ ํ์ํ ๋์์ ์ ๊ณตํฉ๋๋ค. ๋ํ UICollectionViewDataSource ํ๋กํ ์ฝ์ ์ค์ํ๊ณ ํ๋กํ ์ฝ์ ๋ชจ๋ ๋ฉ์๋์ ๋ํ ๊ตฌํ์ ์ ๊ณตํฉ๋๋ค.
๊ตฌํ ์์
- Connect a diffable data source to your collection view.
- Implement a cell provider to configure your collection viewโs cells.
- Generate the current state of the data.
- Display the data in the UI.
1๏ธโฃ
diffable data source ๋ฅผ collection view ์ ์ฐ๊ฒฐํ๊ธฐ ์ํด์๋ init(collectionView:cellProvider:)
์ด๋์
๋ผ์ด์ ๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์ด์ฃผ๊ณ , data source ์ ์ฐ๊ฒฐํ๋ ค๋ collection view ๋ฅผ ์ ๋ฌํฉ๋๋ค.
2๏ธโฃ
๋ํ ๊ฐ ์
์ ๊ตฌ์ฑํ์ฌ UI ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํ๋ cell provider
๋ฅผ ์ ๋ฌํฉ๋๋ค.
dataSource = UICollectionViewDiffableDataSource<Int, UUID>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, itemIdentifier: UUID) -> UICollectionViewCell? in
// Configure and return cell.
}
3๏ธโฃ
๊ทธ๋ฐ ๋ค์, Snapshot
์ ๊ตฌ์ฑํ๊ณ ์ ์ฉํ์ฌ ๋ฐ์ดํฐ์ current state ๋ฅผ ์์ฑํ๊ณ UI ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ค. ๋ ๋ง์ ๋ด์ฉ์ NSDiffableDataSourceSnapshot ๋ฅผ ์ฐธ๊ณ ํ์ญ์์ค.
๐ง Important - diffable data source ๋ก ๊ตฌ์ฑํ ํ collection view ์์ dataSource ๋ฅผ ๋ณ๊ฒฝํ์ง ๋ง์ธ์.
- ๋ง์ฝ collection view ๊ฐ ์ด๊ธฐ ๊ตฌ์ฑํ ํ ์๋ก์ด data source ๋ฅผ ํ์ํ๋ค๋ฉด, ์ collection view ์ diffable data source ๋ฅผ ๋ง๋ค๊ณ ๊ตฌ์ฑํฉ๋๋ค.
โ๋ฌ๋ผ์ง ๋ถ๋ถ์ ์ด๋ป๊ฒ ์์์ฐจ๋ฆฌ๋ ๊ฑธ๊น์?
๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด Hash Value
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Diffable Data Source
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ค์ ๋๊ฐ์ง generic type ์ ๊ฐ์ง๋๋ค.
- section identifier
- item identifier
// Diffalbe Data Source
@MainActorย classย UICollectionViewDiffableDataSource<SectionIdentifierType,ย ItemIdentifierType> :ย [NSObject](https://developer.apple.com/documentation/objectivec/nsobject)ย whereย SectionIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable),ย ItemIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable)
// Snapshot
struct NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable
SectionIdentifierType
,ย ItemIdentifierType
ย ๋๊ฐ์ generic parameter๋ก ๊ฒฐ์ ๋ฉ๋๋ค.
์๋ฃํ์ ๋ณด๋ค์ํผ ๋ ํ๋ผ๋ฏธํฐ๋ ๋ฐ๋์ย Hashable
ย ํด์ผ ํด์. Hashalbe
ํ๊ธฐ ๋๋ฌธ์ apply ํ ๋ ๋น๊ตํด์ ์ถ๊ฐ ๋๋ ์ญ์ ๋ ๋ถ๋ถ์ ์์์ฐจ๋ฆฌ๋๋ก ํ๋ ๊ฒ์
๋๋ค.
2๏ธโฃย ์ฝ๋๋ฅผ ์ง๋ณด์!
1. Connect a diffable data source to your collection view.
DiffableDataSource ๋ ํ๋กํ ์ฝ์ด ์๋๋ผ Generic Class ๋ผ๊ณ ํ์ต๋๋ค.
@MainActorย classย UICollectionViewDiffableDataSource<SectionIdentifierType,ย ItemIdentifierType> :ย [NSObject](https://developer.apple.com/documentation/objectivec/nsobject)ย whereย SectionIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable),ย ItemIdentifierTypeย :ย [Hashable](https://developer.apple.com/documentation/swift/hashable)
- ์ด๋์ ๋ผ์ด์ ๋ฅผ ํตํด์ ๋ง๋ค์ด์ฃผ๊ณ ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค.
@MainActor init(collectionView: UICollectionView, cellProvider: @escaping UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider)
Generic type ๋ถํฐ ์ง์ ํด๋ณด๊ฒ ์ต๋๋ค. SectionIdentifierType
๊ณผ ItemIdentifierType
์ ์ค์ ํ๋ฉด๋ฉ๋๋ค.
๐ซย SectionIdentifierType
๋ง์ ์์ ๋ฅผ ๋ณด๋ Int ํน์ CaseIterable ์ ์ฑํํ๋ enum ์ ์ฌ์ฉํ๋๋ผ๊ตฌ์. ๋น์ฐํ๊ฒ๋ Hashable
๋ฅผ ์ฑํํด์ ์ฌ์ฉํด๋ ์ข์ต๋๋ค!
enum Section: CaseIterable {
case main
}
- cellProvider๋ 3๊ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
collectionView
,ยIndexPath
,ItemIdentifierType
์ ๋๋ค. - data source ์ฝ๋๋ฅผ ๋ค๋ฅธ๊ณณ์์๋ ์ฌ์ฉํด์ผํ๊ธฐ ๋๋ฌธ์ ์ ์ญ๋ณ์๋ก ๋ง๋ค์ด์ ๊ด๋ฆฌํด์ค๋๋ค.
var dataSource: UICollectionViewDiffableDataSource<Section, String>!
//...
self.dataSource = UICollectionViewDiffableDataSource<Section, String>(collectionView: self.collectionView) { collectionView, indexPath, itemIdentifier -> UICollectionViewCell? in
// code
}
โย Hashable ์ด๋ผ๊ณ ํ๋๋ฐ CaseIterable ์ ์ ๊ฐ๋ฅํ๊ฐ์?
CaseIterable
์ ๋ํด์ ์ ๊น ์์๋ด์!
์ ์ฑํํ ๊น์? allCases
๋ผ๋ ํ์
์์ฑ์ ์ป๊ธฐ ์ํจ์ธ๋ฐ์. ์ปดํ์ผ๋ฌ๊ฐ ํ๋กํ ์ฝ ๊ตฌํ์ ์๋์ผ๋ก ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์ฑํ ์ ์ธ๋ง ํด์ฃผ๋ฉด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ด์!
allCases์ ํ์ ์ ํ๋กํ ์ฝ์ ์ ์ธ์ ๋ฐ๋ผ enum ์์ ์ ์์๋ก ๊ฐ์ง๋ Collection ํ์ ์ผ๋ก ์ ํ๋ฉ๋๋ค.
allCases
๋ assoicated value ๊ฐ ํ๋๋ผ๋ ์๋ค๋ฉด ์๋์ผ๋ก allCases
ํ๋กํผํฐ๋ฅผ ๋ง๋ค์ด์ค ์ ์์ด์.
Associated Value์ ๊ฐ์ด ๋ค๋ฅธ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์ case๋ก ์ทจ๊ธํด์ผ ํ๋์ง, ๋ค๋ฅธ case๋ก ์ทจ๊ธํด์ผํ๋์ง ์ปดํ์ผ๋ฌ๊ฐ ํ๋จํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์ ์ด ๊ฒฝ์ฐ๋ ์ง์ allCases ํ๋กํผํฐ๋ฅผ ์ ๊ณตํด์ค์ผ ํฉ๋๋ค.
Hashable
์ ์ ๊น ์ดํด๋ณผ๊น์!
Hashable
์ associated value ์์ดย enum ์ ์ ์ํ๋ฉด ์๋์ผ๋กยHashable
์ ์ค์ํฉ๋๋ค.
์ฆ, associated value ์๋ enum ์ ์๋์ผ๋ก Hashable
์ ์ค์ํ๊ณ , CaseIterable
์ ์ฑํํด์ ์๋์ผ๋ก allCasese
๋ผ๋ ํ์
์์ฑ์ ์ป์๋ค๋๊ฒ์ associated value ๊ฐ ์๋ค๋ผ๋ ๊ฒ์ด๋๊น Hashable ์ ์ค์ํ๋ ๊ฒ์ด์ง์!
๊ทธ๋์ CaseIterable
์ ์ฑํํ๋ ์์ ๋ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ ๊ฒ์ด๋๋๋ค!
- ์ฐธ๊ณ :
๐ซย ItemIdentifierType
๋ณด์ฌ์ค item ์ด String ์ด๋ผ๊ณ ๊ฐ์ ํ๊ณ ๋ฃ์ด์ฃผ๊ฒ ์ต๋๋ค.
- ์ด๋ ๊ฐ์ ๊ฐ์ด ์ค๋ณต์ผ๋ก ๋ค์ด๊ฐ๊ฒ ๋๋ฉด ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค! ๊ทธ๋์ ์ค๋ณต๋ ๊ฐ์ ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํฉ๋๋ค.
โ์ค๋ณต๋ ๊ฐ ์ฒ๋ฆฌ
1๏ธโฃย
UUID ๋ฅผ ํ์ฉํ ํ๋กํผํฐ ์ ์
struct ItemName: Hashable {
let id = UUID()
var name: String
}
2๏ธโฃย
ItemIdentifierType ๋ณ๊ฒฝ
// var dataSource: UICollectionViewDiffableDataSource<Section, String>!
// ๋ณ๊ฒฝ.
var dataSource: UICollectionViewDiffableDataSource<Section, ItemName>!
2. Implement a cell provider to configure your collection viewโs cells.
- cell ์ ๋ง๋ค๊ณ , cell ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ค๋ค.
// cell ์ด ํด๋น collection view ์ register ๋ ์ํ์ฌ์ผ ํ๋ค.
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
self.dataSource = UICollectionViewDiffableDataSource<Section, String>(collectionView: self.collectionView) { collectionView, indexPath, itemIdentifier -> UICollectionViewCell? in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CollectionViewCell else { return UICollectionViewCell() }
// โ
cell ์ด๊ธฐํ.
cell.initCell(itemIdentifier)
return cell
}
collectionView.dataSource = dataSource
3. Generate the current state of the data.
Snapshot
์ ๊ตฌ์ฑํด๋ณด์.
// โ
ํ
์คํธ์ ๋ฐ๋ผ์ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋ฑ์ฅํ๋ ๋ก์ง.
func performQuery(with filter: String?) {
// โ
ํ
์คํธ๊ฐ ๋ค์ด์๋ arr ์์ filter ๋ก ์์ํ๋ ํ
์คํธ๋ค์ ์ ์ฅ.
let filtered = self.arr.filter { $0.hasPrefix(filter ?? "") }
// โ
Snpapshot ์์ฑ.
var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
// โ
section ๋ฐ item ์ถ๊ฐ.
snapshot.appendSections([.main])
snapshot.appendItems(filtered)
// โ
apply ๋ฅผ ํตํด์ snapshot ๊ณผ animatingDifferences ํ๋ผ๋ฏธํฐ ์ ๋ฌ.
// โ
์ฌ๊ธฐ์ ์ฌ์ฉํ๊ธฐ ์ํด์ dataSource ๋ฅผ ์ ์ญ์ ์ธํจ.
self.dataSource.apply(snapshot, animatingDifferences: true)
}
โ๏ธapply snapshot without animation
์์์ ์ฌ์ฉํ apply(_:animatingDifferences:completion:)
๋ฉ์๋์ ๋์์ด iOS 15 ๋ถํฐ ๋ณ๊ฒฝ๋์๋ค.
animatingDifferences
ํ๋ผ๋ฏธํฐ๊ฐtrue
์ด๋ฉด ์ ๋๋ฉ์ด์ ์ด ์ ์ฉ๋๊ณ ,false
๋ฉด ๋ด๋ถ์ ์ผ๋กreloadData
๋ก ๋ฐ๋์ด์ ๋์ํ์๋ค.
iOS 15 ๋ถํฐ
animatingDifferences
ํ๋ผ๋ฏธํฐ๊ฐfalse
๋ฅผ ๋๊ธฐ๋ ๊ฒฝ์ฐ๋ ๋ฐ๋ ๋ถ๋ถ๋ง ์ ์ฉํ๊ณreloadData
๋ก ๋ฐ๋์ด ๋์ํ์ง ์๋๋ค๊ณ ํ๋ค.- ๊ทธ๋ฆฌ๊ณ applySnapshotUsingReloadData(_:completion:) ๋ฉ์๋๊ฐ ์ถ๊ฐ๋์ด์ ๋ฐ๋ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธํ๋ ๊ฒ์ด ์๋๋ผ reload ํ๊ณ ์ถ์ผ๋ฉด ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋๋ค.
4. Display the data in the UI
์์์ ์์ฑํ performQuery(with)
๋ฉ์๋๋ฅผ ํตํด์ UI ์ด ๊ฐฑ์ ์ด ํ์ํ ์์
๋ง๋ค snapshot
๊ณผ ํจ๊ป apply()
๋ฅผ ํธ์ถํด์ UI ๋ฅผ ๊ฐฑ์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค!