项目中,需要在进入 UIViewController 后对它里面的 UITableView 滑动到最底部,那么需要把代码写在 viewDidLoad 中。
下面这一行代码要使得 previewTable 这个UITableView 滑动到最底部的位置。(home.tickTasks 是我对代码中这个 tableView 的数据源,可根据实际需要设置)
self.previewTable.scrollToRow(at: IndexPath.init(row: (Home.tickTasks.count - 1), section: 0), at: .bottom, animated: false)
但是,不管是否需要动画,以上代码总是不能准确地滑动到指定位置,滑动的动作需要一点点时间。
以下使用同步机制来等待一小段时间。
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.previewTable.scrollToRow(at: IndexPath.init(row: (Home.tickTasks.count - 1), section: 0), at: .bottom, animated: false)
}
猜想,是因为代码控制对 tableView 的滑动需要在 tableView 初始化好并且把 cell 的数据加载进来之后,如下代码,若这样写,则会出现 tableView 划不到最底部的情况。
override func viewDidLoad() {
super.viewDidLoad()
bindTableView() // 配置 tableView 的 dataSource、delegate 等信息
loadFromCoreData() // 加载数据到 tableViewCell 中
self.previewTable.scrollToRow(at: IndexPath.init(row: (Home.tickTasks.count - 1), section: 0), at: .bottom, animated: false)
// 此时存在数据未加载完成但滑动动作异步执行,所以未滑到最底部,滑动就被终止了。
}
问题出在于未加载完成就进行界面的滑动,所以我们让对界面滑动稍微延迟 0.01 秒,如下代码所示
override func viewDidLoad() {
super.viewDidLoad()
bindTableView()
loadFromCoreData()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
self.previewTable.scrollToRow(at: IndexPath.init(row: (Home.tickTasks.count - 1), section: 0), at: .bottom, animated: false)
}
}
此时就可以滑动到最底部了,但还有一个小问题,上面的 row 为 Home.tickTasks.count - 1,当 count 为 0 时程序会闪退,因为 index 越界了,所以像下面一样预先判断 count 即可解决问题。
override func viewDidLoad() {
super.viewDidLoad()
bindTableView()
loadFromCoreData()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
if Home.tickTasks.count > 0 {
self.previewTable.scrollToRow(at: IndexPath.init(row: (Home.tickTasks.count - 1), section: 0), at: .bottom, animated: false)
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。