問題

最近使用 RxTableViewSectionedAnimatedDataSource 打造列表時遇到一個問題,就是不論使用 scrollToRow 或是 setContentOffset 的方式都無法滑動到正確的位置

原因

應該是因為使用 table view 的新特性 estimated height 在動態計算高度時錯誤導致滑動到錯誤的位置

Workaround

在 RxDataSource 的 issues 討論串中看到了 cache cell height 的做法,將獲得的高度儲存起來並賦予 table view,呼叫滑動 func 時就不會有高度計算的問題

class ViewController: UIViewController {

    private var cellHeightsDictionary: [String: CGFloat] = [:]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // set table view ...
        tableView.rx.setDelegate(self).disposed(by: disposeBag)
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeightsDictionary[indexPath.cacheKey] = cell.frame.size.height
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return cellHeightsDictionary[indexPath.cacheKey] ?? UITableViewAutomaticDimension
    }
}

private extension IndexPath {
    var cacheKey: String {
        return String(describing: self)
    }
}