UITableView scrollToRow 在添加新行后不再适用于 iOS 11

Posted

技术标签:

【中文标题】UITableView scrollToRow 在添加新行后不再适用于 iOS 11【英文标题】:UITableView scrollToRow no longer works on iOS 11 right after adding a new row 【发布时间】:2017-09-06 12:39:33 【问题描述】:

我注意到一个奇怪的 UITableView 行为,它似乎只发生在 ios 11 设备上。

在插入新行之后(更改数据源然后调用 reloadData,UITableView 在调用scrollToRowscrollToBottom() 方法时不会滚动到该行。

在 iOS 10 或更早版本上执行某些操作时,它可以完美运行,并且 UITable 可以正常滚动。

谢谢!

【问题讨论】:

updateRowAtIndexPath(oldLastRowIndexPath) 方法是什么? @FahriAzimov 刚刚编辑了我的原始问题并添加了该功能。谢谢! 这种情况经常发生吗?我的意思是,当您的旧最后一个单元格可见或不可见时? 强烈建议您切换到UICollectionView。在切换到UICollectionView 之后,我遇到了和你一样的问题,这些问题都消失了。 UICollectionView 在插入、删除、移动和滚动操作上似乎更加流畅。 【参考方案1】:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^

    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
);

在我的情况下添加一个小的延迟是有效的。

【讨论】:

同样的事情最终对我有用,我只是忘了发布我的答案,所以我会接受你的:) 但是,是的,由于某种原因添加延迟有效......跨度> 你归档雷达了吗? 这个问题有bug吗? 但是,另一种可能的解决方法是,将estimatedRowHeight 和estimatedSectionHeaderHeight 赋值为0。这样可以防止iOS 自动调整tableview 的大小和位置。【参考方案2】:

Accepted answer 在 Swift 4 语法中

let deadlineTime = DispatchTime.now() + .seconds(1)
                DispatchQueue.main.asyncAfter(deadline: deadlineTime) 
                    self.tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
                

【讨论】:

为什么是 1 秒?似乎很长一段时间,在大多数情况下,您最初可能期望这是“即时”或至少接近即时。 无论如何,谢谢。我将.seconds(1) 更改为.milliseconds(1),到目前为止一切正常。 我回来了,我怀疑这实际上是一种危险的事情。一旦等待时间结束,您可能希望确保 indexpath 指定的行和节仍然存在。如果行/节超过可用的行/节(它们可能被其他进程删除),scrollToRow 将崩溃。 同意,明智的做法是先检查该特定行和部分是否存在。【参考方案3】:

不确定我遇到的情况是否适用于这个问题,但我也遇到过 UITableView.scrollTo... 从 iOS 11 开始出现行为不端的情况。

在我的情况下,我连续调用UITableView.reload...UITableView.scrollTo...。事实证明,顺序很重要。

这行得通:

tableView.reloadData()
tableView.scrollToRow(at: indexPath, at: .top, animated: true)

这不是:

tableView.scrollToRow(at: indexPath, at: .top, animated: true)
tableView.reloadData()

希望这会有所帮助。

【讨论】:

你是救星!【参考方案4】:

你在 viewDidAppear 中打电话给scrollToRow() 吗?

将函数调用从 viewWillAppear 移动到 viewDidAppear 对我有用。

【讨论】:

这会导致我的应用 (iOS12) 出现明显的跳跃【参考方案5】:

只是 DispatchQueue.main.async 为我工作。

【讨论】:

以上是关于UITableView scrollToRow 在添加新行后不再适用于 iOS 11的主要内容,如果未能解决你的问题,请参考以下文章

Swift 分段控制和 UITableView

UITableView 从当前位置滚动到底部

如何在Swift中的UITableView中截取所选行的屏幕截图并将其保存为UIImage?

scrollToRow(at:at:animated:) SwiftUI

滚动到表视图标题顶部

PB做大屏显示滚动窗口