【问题标题】:RxSwift tableView update based on property基于属性的 RxSwift tableView 更新
【发布时间】:2019-01-24 20:11:00
【问题描述】:

我有一个填充了产品模型的 UITableView。我现在面临两个挑战。第一个是我在单元格上有一个quantityLabel,当用户按下单元格上的递增或递减按钮时,我想更新它。目前为此,我正在更新模型并接受一个全新的数组,这会触发 tableView 重新加载,这并不理想。第二个挑战是,当 Product 的数量变为 0 时,应该使用动画从 tableView 中删除该单元格。目前,我只是在数据源中找到产品的索引,将其删除并重新加载表。我想知道正确的 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
  }
}

【问题讨论】:

    标签: reactive-programming rx-swift


    【解决方案1】:

    您的这两个挑战都可以通过使用RxDataSources Cocoapod 来解决。

    或者,您可以像我在这里所做的那样自己滚动:https://github.com/dtartaglia/RxMultiCounter/blob/master/RxMultiCounter/RxExtensions/RxSimpleAnimatableDataSource.swift

    这里的想法是使用一些东西(我正在使用 DifferenceKit)来确定哪些元素发生了变化,并且只重新加载那些特定的元素。为此,您需要一个专门的数据源对象,而不是 RxCocoa 附带的通用对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多