我有一个带有tableView
的视图控制器,其中有一个部分,我使用RxSwift以下面的方式在其中显示data
。每当data
更改时,我想滚动到tableView
的底部(或其他任何位置)。我使用.xib
文件作为我的单元格和动画数据源。
问题是,有时调用scrollToRow
时,单元格尚未显示在tableView
中,调用会抛出错误。
如何解决这个问题?
我唯一能想到的是在数据更改和滚动之间放置一个延迟,但是延迟应该有多大?我也认为有一些更强大的方法来解决这个问题。一直等到单元格真正显示出来。
我试着做:
scrollRectToVisible(...)
到tableView.contentSize
的底部- 滚动前检查是否
data.count == tableView.numberOfRows(inSection: 0)
这两种情况都会导致tableView
在更新data
时有时不滚动,这比错误好,但仍然不是预期的结果。
class SomeVC: UIViewController {
private typealias DataSource = RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<..., ...>>
private let db = DisposeBag()
@IBOutlet weak var tableView: UITableView!
private let data = BehaviorRelay<[...]>(value: ...)
private lazy var dataSource = createDataSource()
override func viewDidLoad() {
tableView.register(UINib(nibName: ..., bundle: ...), forCellResuseIdentifier: ...)
dataSource.animationConfiguration = AnimationConfiguration(insertAnimation: .bottom, reloadAnimation: .fade, deleteAnimation: .fade)
data
.asDriver()
.do(afterNext: { [unowned self] data in
DispatchQueue.main.async { [weak self] in
let lastIndexPath = getLastIndexPath(from: data)
// This does not always hold: data.count == tableView.numberOfRows(inSection: 0)
self?.tableView.scrollToRow(at: lastIndexPath, at: .none, animated: true)
}
}
.map { [AnimatableSectionModel(...)] }
.drive(tableView.rx.items(dataSource: dataSource))
.disposed(by: db)
}
private func getLastIndexPath(from data: [...]) {
// Something like this
return IndexPath(row: data.count - 1, section: 0)
}
private func createDataSource() -> DataSource {
return DataSource(configureCell: { dataSource, tv, indexPath, model in
let cell = tv.dequeueReusableCell(withIdentifier: ..., for: indexPath)
...
return cell
}
}
}
字符串
1条答案
按热度按时间gojuced71#
下面的工作,但它不是理想的:
字符串
重要的一点,也是最大的问题,这里是两个订阅依赖于顺序。由于它们不是独立的,如果你反转它们,应用程序将无法工作。
这也为我工作。也许你计算最后一行是错误的?
型