RxSwift를 사용하여 Data를 Binding할 시 Data가 변화할 때 마다 Reload하지 않아도 된다는 미친 장점 존재
But, Table, Collection View에서 Header, Footer, Section의 개념을 사용할 수 없어서 이전까지는 Delegate Pattern을 이용하여 구현했었다.
하지만 Example 정보를 나타내는 UI에서 아래 이미지처럼 스크롤 되려면 Header 사용이 필수적이고,
이번 프로젝트에서는 능력 내에서 최대한 깔끔하게 코드를 짜고 싶어 RxDataSource를 사용하기로 결정.
⇒ RxDataSource
public struct SectionModel<Section, ItemType> {
public var model: Section
public var items: [Item]
public init(model: Section, items: [Item]) {
self.model = model
self.items = items
}
}
typealias ExampleSectionModel = SectionModel<SectionExampleModel, ItemExampleModel>
typealias ExampleDataSource = RxCollectionViewSectionedReloadDataSource<ExampleSectionModel>
RxDataSource에 Table, Collection View에 Binding할 모델을 SectionModel로 정의되어있다.
현재 Header에 SectionExampleModel, Item에 ItemExampleModel이 필요하므로 해당 사항에 맞춰 ExampleSectionModel 정의
exampleCollectionView.rx.setDelegate(self).disposed(by: bag)
let dataSource = RxCollectionViewSectionedReloadDataSource<ExampleSectionModel>(configureCell: { (ds, collectionView, indexPath, data) in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ExampleCollectionViewCell.identyfier,
for: indexPath) as? ExampleCollectionViewCell else { return UICollectionViewCell() }
cell.setData(data)
return cell
})
dataSource.configureSupplementaryView = {(ds, collectionView, kind, indexPath) -> UICollectionReusableView in
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: ExampleCollectionHeaderView.identyfier, for: indexPath) as? ExampleCollectionHeaderView else {
return UICollectionReusableView()
}
let section = ds.sectionModels[indexPath.row].model
header.setData(section)
return header
}
Driver.combineLatest(viewModel.section, viewModel.items)
.map { [ExampleSectionModel(model: $0, items: $1)] }
.drive(exampleCollectionView.rx.items(dataSource: dataSource))
.disposed(by: bag)
차례로 ItemExampleModel을 Cell에 Binding - SectiontationsectionModel을 Header에 Binding - SectionExaple, ItemExample Model이 들어올때마다 CollectionViewDataSource에 Driving하는 형태.
⚠️ RxDataSource에서는 Compoment의 Configuration이 완료된 이후에 Binding, Driving 등의 작업이 가능하므로 주의!
➕ 다음에는 Cell, Header 같은 components를 XIB(NIB) 형태로 구현해보자.
매번 귀찮아서 Delegate 패턴으로 하다가 드디어 RxDataSource 해결,,