基于属性的 RxSwift tableView 更新

Posted

技术标签:

【中文标题】基于属性的 RxSwift tableView 更新【英文标题】:RxSwift tableView update based on property 【发布时间】: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
  

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

以上是关于基于属性的 RxSwift tableView 更新的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 RxSwift 为空 tableView 显示 backgroundVIew

使用 RxSwift 对成员“tableView”的模糊引用

RxSwift TableView - 如何设置 numberOfRowsInSection?

RxSwift 如何知道 TableView 重新加载结束

如何在 RxSwift 中将多个数据模型绑定到 TableView

正确使用 RxSwift 和 TableView