RxDataSources
- TableView, CollectionView를 Section을 사용해서 정의가능한 프레임워크
- Rx를 사용한 반응형 데이터 적용
- cellForRowAt을 사용하지 않고 cell데이터 지정
- Link
Section정의
RxDataSource에 사용될 DataType은 SectionModelType을 준수
items는 cell데이터 타입 등록
struct SectionOfMain {
var items: [Item]
}
extension SectionOfMain: SectionModelType {
typealias Item = MainCellData
init(original: Self, items: [Item]) {
self = original
self.items = items
}
}
CellData정의
Section안에 정의한 item enumType으로 설정
(cellType은 TableView cell register부분에서 한번에 등록하기 위한 변수)
enum MainCellData {
case main(title: String, isFocus: Bool)
case sub(title: String)
var cellType: MainCellDataProtocol.Type {
switch self {
case .main: return MainCell.self
case .sub: return SubCell.self
}
}
}
protocol MainCellDataProtocol: AnyObject {
func apply(item: MainCellData) // data 적용
static func cellHeight(item: MainCellData) -> CGFloat // 동적 height설정
}
Cell정의
위에서 정의한 MainCellDataProtocol을 준수하는 Cell정의
class MainCell: UITableViewCell, MainCellDataProtocol {
let titleLabel: UILabel = {
let label = UILabel()
label.text = "main"
label.textColor = .purple
label.font = .systemFont(ofSize: 20)
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
}
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func apply(item: MainCellData) {
guard case let .main(title, isFocus) = item else { return }
titleLabel.text = title
titleLabel.font = isFocus ? .boldSystemFont(ofSize: 20) : .systemFont(ofSize: 20)
}
static func cellHeight(item: MainCellData) -> CGFloat {
return 70
}
}
TabelView RxDataSource적용
// dataSource선언
private var dataSource: RxTableViewSectionedReloadDataSource<SectionOfMain>?
private func setupDataSource() {
// dataSource정의 (기존 tableView(_: cellForRowAt.. 부분)
let dataSource = RxTableViewSectionedReloadDataSource<SectionOfMain> {
_, tableView, indexPath, item in
let cellId = String(describing: item.cellType)
tableView.register(item.cellType, forCellReuseIdentifier: cellId)
tableView.register(item.cellType, forCellReuseIdentifier: cellId)
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
(cell as? MainCellDataProtocol)?.apply(item: item)
return cell
}
self.dataSource = dataSource
// viewModel의 sections binding
viewModel.sections
.observe(on: MainScheduler.instance)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
github linkg: https://github.com/motosw3600/RxDataSourceEx
'swift' 카테고리의 다른 글
DropDown 오픈소스 라이브러리 만들기 (0) | 2022.08.10 |
---|---|
Custom ScrollPaging (0) | 2022.06.05 |
RxSwift UnitTest 해보기(RxTest, RxNimble) (0) | 2022.03.10 |
Tuist로 프로젝트 관리해보기 (0) | 2022.03.05 |
The Composable Architecture(TCA) (0) | 2022.03.02 |