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