😡 야심차게 Rx로 컬렉션뷰/테이블뷰를 구성했는데 .. 갑자기 .. 섹션이 필요하다..? 그럼 RxDataSource를 쓰세요..
RxDataSource를 사용해야 하는 이유❓
Rx를 통해 collectionView를 바인딩해서 사용하고 있었습니다 ..
섹션이 하나인 경우에는 RxSwift , RxCocoa dataSource 만으로도 충분히 사용할 수 있는데,
섹션이 여러개가 되는 경우에는 구현이 조금 어렵습니다.
이런 경우 RxDataSource를 통해 여러 섹션의 여러 아이템을 넣어 구현할 수 있습니다.
GitHub - RxSwiftCommunity/RxDataSources: UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates,
UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...) - GitHub - RxSwiftCommunity/RxDataSources: UITableView and UICollectionView Data Sources for RxSw...
github.com
사용해보겠슴니다 🔫
아래는 RxDataSource를 적용하기 전의 컬렉션뷰입니다.
한 줄에 최대 3개의 태그만 들어가야 하며, 태그별로 길이가 달랐기 때문에
섹션을 통해 한 섹션에 3개의 태그씩 들어가게 하려 합니다.
1️⃣ pod install
pod 'RxDataSources', '~> 5.0'
먼저 pod을 설치해줍니다. 위에 있는 RxDataSource 깃허브에 들어가도 확인하실 수 있슴니다.
2️⃣ section model 만들기
섹션으로 나눠서 데이터를 넣어주기 위한 모델을 만들어줍니다.
struct CategorySectionModel {
// var header: String
var items: [Category]
init(items: [Category]) {
self.items = items
}
// header을 받는 경우
// init(header: String, item: [Category]) {
// self.header = header
// self.items = items
// }
}
extension CategorySectionModel: SectionModelType {
typealias item = Category
init(original: CategorySectionModel, items: [item]) {
self = original
self.items = items
}
}
제가 받고자 하는 데이터 리스트가 섹션별 카테고리의 리스트이기 때문에
Category의 배열을 items로 받았습니다.
또한 섹션의 헤더 타이틀을 받는 경우, header을 선언해서 받는 등 섹션별로 넣고자 하는 데이터를 추가해주시면 됩니다.
이런 section에 넣을 데이터 모델은 위와 같이
SectionModelType을 준수해야 SectionModel로 활용할 수 있습니다.
public protocol SectionModelType {
associatedtype Item
var items: [Item] { get }
init(original: Self, items: [Item])
}
3️⃣ DataSource 구현
다음에로 VC에서 사용할 dataSource를 구현해줬습니다.
private lazy var dataSource = RxCollectionViewSectionedReloadDataSource<CategorySectionModel> (configureCell: { dataSource, collectionView, indexPath, item in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoryCVC.className, for: indexPath) as? CategoryCVC else { return UICollectionViewCell() }
cell.categoryLabel.text = item.rawValue
return cell
})
RxCollectionViewSectionedReloadDataSource를 통해 dataSource 객체를 만들었고,
이 객체는 SectionModelType를 받기 때문에 앞에서 생성한 CategorySectionModel을 넣어줬습니다.
configureCell은 dataSource, collectionView, indexPath, item을 받아 cell을 리턴하는 클로져로,
여기서 아이템은 CategorySectionModel의 item을 말합니다 !
items의 item을 받아와 셀의 categoryLabel.text에 넣어줬습니다.
struct CategorySectionModel {
var items: [Category]
init(items: [Category]) {
self.items = items
}
}
extension CategorySectionModel: SectionModelType {
**typealias item = Category**
init(original: CategorySectionModel, items: [item]) {
self = original
self.items = items
}
}
4️⃣ 바인딩..
let section = [
CategorySectionModel(items: [Category.novel, Category.essay, Category.human]),
CategorySectionModel(items: [Category.health, Category.social, Category.hobby]),
CategorySectionModel(items: [Category.history, Category.religion, Category.home]),
CategorySectionModel(items: [Category.language, Category.travel, Category.computer]),
CategorySectionModel(items: [Category.magazine, Category.comic, Category.art]),
CategorySectionModel(items: [Category.improve, Category.economy])
]
Observable.just(section)
.bind(to: categoryCV.rx.items(dataSource: dataSource))
.disposed(by: self.disposeBag)
넣고자 하는 섹션별로 구성된 CategorySectionModel의 배열을 section이라는 이름으로 만들어줬습니다.
첫번째 섹션에는 Category.novel, Category.essay, Category.human이라는 세개의 아이템을,
두번째 섹션에는 Category.health, Category.social, Category.hobby 라는 세개의 아이템을 넣겠다는 의미입니다 ! ..
5️⃣ 끝
그럼 이렇게 원하는 대로 섹션 당 원하는 개수의 셀만큼 구성할 수 있습니다 !
테이블뷰도 마찬가지로 구성하시면 됩니다 !
'iOS' 카테고리의 다른 글
[iOS] Compositional Layout 💂♀️ (0) | 2022.09.05 |
---|---|
[iOS] 컴포넌트를 코드베이스, 스토리보드에서 둘다 쓸 수 있도록 하는 방법🐯 (1) | 2022.05.30 |
[iOS] Haptic 사용법👋 (0) | 2022.04.23 |
[iOS] Diffable Datasource❓ (0) | 2022.03.18 |
[iOS] Notification Center 📡 (0) | 2022.03.14 |