Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift - Textfield-Variable binding in tableview

I'm new to RxSwift and I have this code to setup a tableview which contains a textfield:

budget.expenses.asObservable()
  .bindTo(tableView.rx.items(cellIdentifier: ExpenseInputCell.cellIdentifier, cellType: ExpenseInputCell.self)){(row, element, cell) in

  cell.name.text = element.name.value
  cell.name.rx.text
    .bindTo(element.name)
    .addDisposableTo(self.disposeBag)
}
.addDisposableTo(disposeBag)

tableView.rx.itemDeleted
  .subscribe(onNext: {indexPath in
    self.budget.expenses.value.remove(at: indexPath.row)
  })
  .addDisposableTo(disposeBag)

Everything works fine until a row is deleted, because then the binding of the textfield to the correct object in the array is mixed up. For example lets say I have 7 items in the tableview and I delete the 5th row, the new 5th and 6th row both have the same value

like image 928
user2529173 Avatar asked Sep 17 '25 03:09

user2529173


1 Answers

The problem lies in the lifecycle of the subscription to element.name. Because it is tied to self.disposeBag, it will not be dismissed when the cell is reused, but when self is.

You probably want to expose a new dispose bag on ExpenseInputCell and renew it in cell's prepareForReuse method.

class ExpenseInputCell: UITableViewCell {
  // ..

  var disposeBag = DisposeBag()

  override func prepareForReuse() {
    self.diposeBag = DisposeBag()
  }
}

and in view controller

budget.expenses.asObservable()
  .bindTo(tableView.rx.items(cellIdentifier: ExpenseInputCell.cellIdentifier, cellType: ExpenseInputCell.self)){(row, element, cell) in

  cell.name.text = element.name.value
  cell.name.rx.text
    .bindTo(element.name)
    .addDisposableTo(cell.disposeBag)
}
.addDisposableTo(disposeBag)
like image 134
tomahh Avatar answered Sep 19 '25 19:09

tomahh