Hello World
groove's Introduction
groove's People
groove's Issues
컬렉션 뷰의 Data Source에 한 개 이상의 타입의 Item을 받도록 하려면 어떻게 해야할까?
Context of the problem
현재 데이터소스 및 스냅샷의 ItemIdentifier 타입은 Playlist 로 정의하고 있다.
// data source
UICollectionViewDiffableDataSource<Section, Playlist>
// snapshot
NSDiffableDataSourceSnapshot<Section, Playlist>()
그렇기 때문에 데이터 소스에서 Cell을 dequeue할 때 받는 인자의 타입 또한 Playlist다.
dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView)
{(
collectionView: UICollectionView,
indexPath: IndexPath,
playlist: Playlist // Item Identifier type: Playlist
) -> UICollectionViewCell? in
...
}
이렇게 해서 데이터소스에 정의한 Item Identifier이 Playlist 이기 때문에 Cell의 아이템에는 Playlist만 올 수 있다.
만약 컬렉션 뷰에 아이템에 Playlist 만 보여준다면 아무런 문제가 없겠지만, 이 컬렉션 뷰에는 Playlist가 가지고 있는 Track 타입의 아이템도 보여주어야 한다.
컬렉션 뷰의 데이터 소스가 한 개 이상의 타입의 아이템을 받도록 해야한다.
Brain Storming
가장 먼저 구글링을 했다. collectionview compositional layout diffable data source multiple data source item type 즘으로 검색했던 것으로 기억한다. 운이 좋게도 내가 고민한 부분에 있어서 풀어낸 포스트를 찾을 수 있었다.
Ahmed라는 분은 데이터 소스의 ItemIdentifier 타입에 AnyHashable 을 오게 해서 Hashable 프로토콜을 준수하는 모든 아이템 타입이 올 수 있도록 확장(?)시켜주었다.
var dataSource: UICollectionViewDiffableDataSource<Section<AnyHashable, [AnyHashable]>, AnyHashable>?
이 분은 Media 랑 Category란 두가지 타입의 아이템을 컬렉션 뷰의 아이템으로 보여주고자 하고 있다. 데이터 소스에서 cell을 dequeue할 때 item 을 각 타입으로 타입 캐스팅하여 사용한다.
func configureDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section<AnyHashable, [AnyHashable]>, AnyHashable>(collectionView:
collectionView) { (collectionView, indexPath, item) -> UICollectionViewCell? in
if let media = item as? Movie { // AnyHashable -> Movie 타입 캐스팅
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: SmallCollectionViewCell.identifier,
for: indexPath) as? SmallCollectionViewCell else { return UICollectionViewCell() }
cell.configure(with: media)
return cell
}
if let categorey = item as? Categorey { // AnyHashable -> Movie 타입 캐스팅
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: CategoryCollectionViewCell.identifier,
for: indexPath) as? CategoryCollectionViewCell else { return UICollectionViewCell() }
cell.configure(with: categorey)
return cell
}
return nil
}
}
현재 내가 ItemIdentifier로 사용하고자 하는 타입은 plist 파일 디코딩하여 생성하기 때문에 위의 예제와 마찬가지로 Hashable 프로토콜을 준수하고 있다.
나는 데이터소스가 다른 타입의 아이템을 받을 수 있도록 메서드를 추가해줘야 되는 방향으로 생각하고 있었다. 그치만 구글링과 개발자 문서를 찾아보았지만 그럴 수 있는 방법은 없었다. 그런데 데이터 소스가 제네릭 타입으로 구현이 되어있어서 위와 같이 조금 더 상위 타입? 추상 타입의 아이템을 받도록 정의하니 메서드를 추가해줄 필요가 전혀 없다는 것을 깨달았다. 제네릭으로 구현이 되어있지 않았다면 같은 코드를 중복해서 작성해야하는 번거로움이 있었을 텐데, 이렇게 추상 타입을 받도록 하니 그런 번거로움이 사라졌다. (이런 포인트에서 제네릭 타입이 매우 유용하다는 것을 새삼 느끼고 있다.)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.