表題の通り、reloadData() 完了後に何か処理したい場合、公式的なやり方(ハンドラやらデリゲートやら)がないので、代替案を探してました。
やりたいこととしては更新後にトップに移動したかったのですが、この移動時のアニメーションを綺麗にしてーんですよ!
アニメーションなしとか生理的に無理!笑
開発環境(前提条件)
・Xcode12.5
・Swift5
ダメコード
他の記事や StackOverFlow では、以下のような提案をしている方が多かったです。
UIView.animate(withDuration: 0.0, animations: {
self.tableView.reloadData()
}) { (finished) in
//完了後の処理
}
「いいアイディアやんけ(内部で何してんの…)」と思いつつ、
更新完了後にテーブルのトップに移動したくて、
setContentOffset(_:animated:) を記載したのですが、中途半端に移動します…
UIView.animate(withDuration: 0.0, animations: {
self.tableView.reloadData()
}) { (finished) in
self.tableView.setContentOffset(.zero, animated: true)
// self.tableView.contentOffset = .zero も動かない
}
メインスレッドにしても変わりませんでした。w
綺麗に動いたコード
で、結局どうやったかというと、
UIView.animate(withDuration: 0.0, animations: {
self.tableView.reloadData()
}) { (finished) in
self.tableView.layoutIfNeeded()
self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
//----- アニメーションなくても大丈夫 -----//
// self.tableView.reloadData()
// self.tableView.layoutIfNeeded()
// self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
UITableView のインスタンスメソッド、scrollToRow(at:at:animated:) で移動しました!
これなら綺麗にアニメーションもしてくれます。
先頭に移動するくらいなら offset で指定していいかーと思ってたのですが、
layoutIfNeeded で再配置後に setContentOffset(_:animated:) しても綺麗に動きませんでした。
更新後に移動させるときはこの方法が綺麗だと思います (`・ω・´)
さいごに
とりあえず目標だった動きにはなりました。
違うよ!とかこういう方法あるよ!ってのがあれば教えてください。
では( ¯·ω·¯ )



コメント