UITableViewCellの中身をRxで監視するときのtips
シナリオ
- テキスト入力をもつTableViewCellがある
- 画面には更新ボタンがあり、押した時に、キーボードを閉じたい
結論ソース
※諸々省略してます
// UITableViewCellにcellForRowAtIndexまでにunbindさせるための情報を定義する extension Reactive where Base: UITableViewCell { var prepairForReuse: Observable<Void> { return methodInvoked(#selector(base.prepareForReuse)) .map { _ -> Void in return Void() } } var obsolete: Observable<Void> { return Observable.merge(prepairForReuse, deallocated) } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as TextCell weak var weakCell = cell updateButton.rx.tap .takeUntil(cell.rx.obsolete) .subscribe(onNext: { [weak self] _ in weakCell?.closeKeyboard() }) .disposed(by: disposeBag) } }
sentMessageでprepairForReuseを監視
prepairForResuseとdeallocのどちらかのイベントを受け取るまで監視しておけば良いので、それらをまとめてobsoleteというイベントを生やしました。
これをしないと、tableViewをスクロールするたびにsubscribeが増えるので予期せぬ動作を引き起こす可能性がある。