特定のインデックス(_self.boldRowPath
_)までスクロールしたいのですが、デバッグ時にはscrollToRow
がreloadData()
の前に実行されます。
reloadData
が終了したことを知る方法は?
_func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
_
どんな助けでも大歓迎です。
これを試してみてください、それはうまくいくはずです:
self.tblTimeEvent.reloadData()
DispatchQueue.main.async(execute: {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
})
これはメインスレッドでscrollToRowを実行します。つまり、reloadDataが実行された後です(メインスレッド上にあるため)。
この答え で説明されているように、UITableView
のリロードは次のレイアウト実行時に行われます(通常、実行ループに制御を戻すとき)。
したがって、メインのディスパッチキューを使用して、次のレイアウトの後にコードをスケジュールできます。あなたの場合:
func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
DispatchQueue.main.async {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
}
layoutIfNeeded
を手動で呼び出して、レイアウトを強制することもできます。しかし、これは一般に良い考えではありません(前のオプションが最適です)。
func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
self.tblTimeEvent.layoutIfNeeded()
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
リロードが...を使用して行われていることを確認できます
In Swift 3.0 +以下のようなescaped Closure
を使用してUITableView
の拡張を作成できます。
extension UITableView {
func reloadData(completion: @escaping () -> ()) {
UIView.animate(withDuration: 0, animations: { self.reloadData()})
{_ in completion() }
}
}
そして、あなたが望むどこでも以下のように使用してください:
Your_Table_View.reloadData {
print("reload done")
}
これが誰かに役立つことを願っています。乾杯!
画面上の可視セクションに対して最後にtableView(_:willDisplay:forRowAt:)
が呼び出されたときにUITableView
がリロードされたというかなり堅固な仮定を立てることができます。
したがって、次のようなものを試してください(セクション0の行が画面上の使用可能なスペースを占めるtableViewの場合)。
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastRowIndex = tableView.numberOfRows(inSection: 0)
if indexPath.row == lastRowIndex - 1 {
// tableView done reloading
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
}
そのためにCATransactionを使用できます
CATransaction.begin()
CATransaction.setCompletionBlock {
// Completion
}
tableView.reloadData()
CATransaction.commit()
tableView.reloadData { [weak self] in
self?.doSomething()
}