[RxDataSources] README

brick·2022년 11월 3일
0
post-thumbnail

💡Why



기존의 table과 collection view에서의 방법들보다 간단하게 구현할 수 있는 delegate method들이 많이 있습니다.

RxSwif는 간단한 data binding을 통해 짐을 덜어줍니다.

  1. data를 Observable sequence로 바꿔줍니다.
  2. 다음을 사용해서 data를 bind 합니다
    • rx.items(dataSource:protocol<RxTableViewDataSourceType, UITableViewDataSource>)
    • rx.items(cellIdentifier:String)
    • rx.items(cellIdentifier:String:Cell.Type:_:)
    • rx.items(::)

let data = Observable<[String]>.just(["first element", "second element", "third element"])

data.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { index, model, cell in
  cell.textLabel?.text = model
}
.disposed(by: disposeBag)

이런 방법은 간단한 data 세트에서는 잘 작동하지만 section이 많은 복잡한 data set인 경우, adding/modifying/deleting 할때 animation 수행이 필요할때 잘 작동하지 않습니다.



💡How



다음 data structrue를 사용한다.

struct CustomData {
  var anInt: Int
  var aString: String
  var aCGPoint: CGPoint
}

  1. SectionModelType protocol을 따르는 struct로 section을 정의한다.
struct SectionOfCustomData {
  var header: String    
  var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
  typealias Item = CustomData

   init(original: SectionOfCustomData, items: [Item]) {
    self = original
    self.items = items
  }
}

  1. dataSource 객체를 만들고 SectionOfCustomData 타입을 전달한다.
let dataSource = RxTableViewSectionedReloadDataSource<SectionOfCustomData>(
  configureCell: { dataSource, tableView, indexPath, item in
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    cell.textLabel?.text = "Item \(item.anInt): \(item.aString) - \(item.aCGPoint.x):\(item.aCGPoint.y)"
    return cell
})
  1. 필요에따라 dataSource의 closure를 커스텀합니다.
dataSource.titleForHeaderInSection = { dataSource, index in
  return dataSource.sectionModels[index].header
}

dataSource.titleForFooterInSection = { dataSource, index in
  return dataSource.sectionModels[index].footer
}

dataSource.canEditRowAtIndexPath = { dataSource, indexPath in
  return true
}

dataSource.canMoveRowAtIndexPath = { dataSource, indexPath in
  return true
}

  1. CustomData의 Observable sequence로 실제 data를 정의한다.
let sections = [
  SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]),
  SectionOfCustomData(header: "Second section", items: [CustomData(anInt: 2, aString: "two", aCGPoint: CGPoint(x: 2, y: 2)), CustomData(anInt: 3, aString: "three", aCGPoint: CGPoint(x: 3, y: 3)) ])
]

Observable.just(sections)
  .bind(to: tableView.rx.items(dataSource: dataSource))
  .disposed(by: disposeBag)

RxdataSoureces는 자동으로 animating 변화를 관리해주는 두가지 data source 타입이 있습니다.

  • RxTableViewSectionedAnimatedDataSource
  • RxCollectionViewSectionedAnimatedDataSource

2개의 data source중 하나를 사용하려면 몇 가지 추가 단계가 필요합니다.

  • SectionOfCustomData는 AnimatableSectionModelType를 준수해야합니다.
  • 당신의 data model은 다음을 준수해야합니다.
    • IdentifiableType: 프로토콜에의해 제공된 identity는 그 모델의 인스턴스를텍스트 대표하는 immutable(변경될 수 없는) identifier입니다.
    • Equatable: RxDataSources가 어떤 cell이 변화했는지 결정하는 것을 도와줍니다. 그래서 이런 셀들이 animate할 수 있게합니다. Car model의 property의 변화가 셀의 animated reload를 발생시킵니다.

0개의 댓글