CollectionView 에서 RxDataSources를 쓰려면 우선
CellModel : Cell에 들어갈 데이터 구조
SectionModel : RxDataSources가 요구하는 구조, 섹션의 데이터 구조
ViewModel : 비즈니스 로직
CollectionViewCell : Cell UI
ViewController : CollectionVeiw UI
가 필요하다
CellModel에서는 Cell에 들어가는 데이터 구조를 먼저 정의해준다.
import Foundation
struct Beach {
let name: String
let imageName: String
let temperature: String
let weatherStatus: String
}
SectionModel에서는 RxDataSources가 요구하는 구조를 만들어준다. 섹션의 데이터 구조임.
import RxDataSources
// 섹션의 데이터 구조
struct BeachSection {
var items: [Beach]
}
extension BeachSection: SectionModelType {
// 섹션 안에 있는 아이템의 타입을 알려줌.
typealias Item = Beach
// 새로운 섹션이 생길때 생성자 호출.
init(original: BeachSection, items: [Beach]) {
self = original
self.items = items
}
}
섹션에는 여러개의 셀이 들어가므로, 셀을 배열 구조로 정의해준다.
cf) var header: String 추가 가능
RxDataSources에서 섹션 모델을 사용하려면, 반드시 SectionModelType 프로토콜을 채택해야함.
public protocol SectionModelType {
associatedtype Item
var items: [Item] { get }
init(original: Self, items: [Item])
}
뷰 모델을 정의해준다.
섹션 모델(BeachSection)을 가져와서 [BeachSection]타입의 Observable로 바꿔줌.
import Foundation
import RxSwift
final class SurferCategoryViewModel {
func fetchBeachSections() -> Observable<[BeachSection]> {
let beaches = [
Beach(name: "경포해변", imageName: "beach1", temperature: "21°C", weatherStatus: "맑음"),
Beach(name: "속초해수욕장", imageName: "beach2", temperature: "19°C", weatherStatus: "흐림")
]
let section = BeachSection(items: beaches)
return Observable.just([section])
}
}
이제 생성된 Observable을 구독하기 위해 ViewController를 만들어준다.
CollectionView에서 사용될 데이터 소스를 정의해줌.
//ViewController
// BeachSection 기반 컬렉션 뷰를 구성하기 위한 제네릭 타입의 데이터 소스.
private lazy var dataSource = RxCollectionViewSectionedReloadDataSource<BeachSection>(
//SectionModel, collectionView, indexPath, item 순
configureCell: { _, collectionView, indexPath, item in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: SurferCell.self), for: indexPath) as? SurferCell else {
return UICollectionViewCell()
}
cell.configure(with: item)
return cell
})
private func bindViewModel() {
viewModel.fetchBeachSections()
.bind(to: collection.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
'iOS' 카테고리의 다른 글
[iOS]2025.06.04 Stack을 왜 쓸까? (0) | 2025.06.04 |
---|---|
[iOS]2025.05.27 트러블 슈팅(스와이프, RxGesture) (0) | 2025.05.27 |
[iOS] 2025.04.13 오늘의 꿀팁 (0) | 2025.04.13 |
[iOS] 2025.03.24 클래스와 구조체 (0) | 2025.03.24 |
[iOS] 2025.03.20 과제 트러블 슈팅 (0) | 2025.03.20 |