Swift 4中viewDidLoad时滚动到最后一条消息的实现问题
解决Swift 4中UITableView在viewDidLoad时滚动到最后一条消息的问题
我来帮你搞定这个问题~你遇到的崩溃原因很明确:iOS所有UI相关操作必须在主线程执行,你之前把scrollToRow放在了后台队列(DispatchQueue.global)里,这直接违反了UI线程的规则,所以才会触发EXC_BAD_ACCESS错误。
第一步:修正scrollToBottom函数
把UI操作切回主线程,同时加上数组非空判断避免索引越界(毕竟如果消息数组是空的,count-1会变成-1,也会出问题):
func scrollToBottom() { DispatchQueue.main.async { // 先判断是否有消息,避免索引越界 guard self.messageArray.count > 0 else { return } let indexPath = IndexPath(item: self.messageArray.count - 1, section: 0) self.messageTableView.scrollToRow(at: indexPath, at: .bottom, animated: true) } }
(另外注意你代码里的变量名messageArrat应该是笔误,改成messageArray更规范哦)
第二步:选择合适的调用时机
在viewDidLoad里直接调用的话,有时候UITableView的布局还没完全完成,滚动操作可能不会生效。这里有两个稳妥的方案:
方案1:在viewDidAppear中调用
当视图完全展示后,布局已经确定,此时滚动肯定生效:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) scrollToBottom() }
方案2:在viewDidLoad中等待布局完成后调用
如果你一定要在viewDidLoad里执行,可以先让tableView完成布局再滚动:
override func viewDidLoad() { super.viewDidLoad() // 设置代理和数据源 messageTableView.delegate = self messageTableView.dataSource = self // 先刷新数据确保tableView有内容 messageTableView.reloadData() // 强制完成当前布局 messageTableView.layoutIfNeeded() // 再执行滚动 scrollToBottom() }
这样调整后,就能正常滚动到最后一条消息啦~
内容的提问来源于stack exchange,提问作者user9183203
相关产品推荐
相关产品推荐

