RxSwift tableView基于属性的更新

时间:2019-01-24 20:11:01

标签: reactive-programming rx-swift

我有一个用产品模型填充的UITableView。我现在有2个挑战。第一个是我在单元格上有一个quantityLabel,当用户按下单元格上的递增或递减按钮时,我想对其进行更新。目前,我正在更新模型并接受一个全新的数组,这会触发tableView重新加载,这并不理想。第二个挑战是,当产品的数量变为0时,应使用动画从tableView中删除该单元格。目前,我只是在dataSource中找到产品的索引,将其删除并重新加载该表。我想知道执行此操作的正确Rx方法。这是我的代码示例。谢谢!

struct Product: Equatable {
  var i: String
  var quantity: Int
  init(i: Int, quantity: Int) {
    self.i = "item: \(i)"
    self.quantity = quantity
  }
}
extension Product {
  static func ==(lhs: Product, rhs: Product) -> Bool {
    return lhs.i == rhs.i
  }
}

class ProductSource {
  var items: BehaviorRelay<[Product]> = BehaviorRelay<[Product]>(value: [])
  var itemsObservable: Observable<[Product]>
  init() {
    itemsObservable = items.asObservable().share(replay: 1)
    items.accept((0..<20).map { Product(i: $0, quantity: 2) })
  }

  func add(product: Product) {}

  func remove(product: Product) {
    guard let index = self.items.value.index(of: product) else {return}

  // decrement quantity, if quantity is 0, remove from the datasource and update the tableView
  }
}

class ViewController: UIViewController {

  @IBOutlet weak var tableView: UITableView!
  var disposeBag = DisposeBag()
  var data = ProductSource()

  override func viewDidLoad() {
    super.viewDidLoad()

    tableView.rx.setDelegate(self).disposed(by: disposeBag)
    data.itemsObservable
        .bind(to: tableView.rx.items(cellIdentifier: "productCell", cellType: ProductTableViewCell.self)) { row, element, cell in
            cell.nameLabel.text = element.i
            cell.quantityLabel.text = String(element.quantity)
    }.disposed(by: disposeBag)
  }
}

extension ViewController: UITableViewDelegate {
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100
  }
}

1 个答案:

答案 0 :(得分:0)

使用RxDataSources Cocoapod可以解决您的两个难题。

或者,您也可以像在这里一样滚动自己的位置:https://github.com/dtartaglia/RxMultiCounter/blob/master/RxMultiCounter/RxExtensions/RxSimpleAnimatableDataSource.swift

这里的想法是使用某些东西(我正在使用DifferenceKit)来找出更改了哪些元素,然后仅重新加载这些特定元素。为此,您需要一个专用的数据源对象,而不是RxCocoa随附的通用对象。