[英]TableView scrollToRow is blocking the main ui thread
I have a UITableView
with about 500 items. 我有一个约500个项目的
UITableView
。
When i call tableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
the main UI thread is getting blocked for 3 seconds. 当我调用
tableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
,主UI线程被阻塞3秒钟。
Is there a way to fix this? 有没有办法解决这个问题? or is the problem scrolling 500 items?
还是滚动500个项目时出现问题?
Thanks 谢谢
the problem is not with reloadData
it was with scrollToRow
问题不在于
reloadData
,而在于scrollToRow
From discussion about how to use a table view for chat: We can use a table view which uses a transform to flip the Y coordinate. 从有关如何使用表格视图进行聊天的讨论中:我们可以使用表格视图,该表格视图使用转换来翻转Y坐标。 We then need to do the same for each of the cells so they are not upside down.
然后,我们需要对每个单元进行相同的操作,以使它们不会倒置。
The procedure is to build a normal messaging table view where the newest message is on top (instead of bottom). 该过程是建立一个普通的消息传递表视图,其中最新消息位于顶部(而不是底部)。 Then put the table view on some superview and invert its coordinate system:
然后将表格视图放在某个超级视图上并反转其坐标系:
chatContainer?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
The cell containing the messages should also have some sort of superview for all the contents which needs to be flipped: 对于所有需要翻转的内容,包含消息的单元格还应该具有某种超级视图:
override func awakeFromNib() {
super.awakeFromNib()
containerView?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
}
So the cell is basically flipped twice so it is shown correctly. 因此,该单元格基本上翻转了两次,因此可以正确显示。
Use time profiler to identify where exactly is the issue. 使用时间分析器来确定问题出在哪里。 The thing is that in general the
UITableView
performance is not effected by a number of items loaded. 问题是,通常,
UITableView
性能不受加载的许多项目的影响。 The view itself will load as many items as it needs to fill the whole screen. 视图本身将加载整个屏幕所需的任意数量的项目。
You may test this by logging a method in a cellForRowAtIndexPath
. 您可以通过在
cellForRowAtIndexPath
记录一个方法来进行测试。 So I am guessing this method may be the one that is slow. 因此,我猜想这种方法可能很慢。 Check how you access the data from it, maybe there is some heavy logic on it.
检查如何从中访问数据,也许上面有一些繁琐的逻辑。 Or the cell layout may be bugged and very slow.
否则单元布局可能会出错并且非常缓慢。
In a general case if you have extremely large amount of data consider using core data and NSFetchedResultsController
which is designed specifically for this situations. 通常,如果您有大量数据,请考虑使用核心数据和专门为这种情况设计的
NSFetchedResultsController
。 But still note that loading 500 elements in a table view should work smoothly without any special optimizations. 但仍需注意,在没有任何特殊优化的情况下,在表视图中加载500个元素应该可以顺利进行。
You should do something like this; 你应该做这样的事情; If user scroll down from top to bottom of the tableview scrollview delegate method fire its "scrollViewDidScroll" method and detect if user bottom of tableview or not then fetch other data and append your array and reload the tableview.
如果用户从表视图的顶部向下滚动到底部,则scrollview委托方法将触发其“ scrollViewDidScroll”方法并检测用户表底部是否存在,然后获取其他数据并追加数组并重新加载表视图。 Thats it!
而已!
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat actualPosition = scrollView_.contentOffset.y;
CGFloat contentHeight = scrollView_.contentSize.height - (someArbitraryNumber);
if (actualPosition >= contentHeight) {
[self.newsFeedData_ addObjectsFromArray:self.newsFeedData_];
[self.tableView reloadData];
}
}
I'm not 100% sure about this solution, didn't had that problem myself. 我不确定这个解决方案100%,我自己也没有遇到这个问题。 Maybe just dispatch it?
也许只是派遣它?
extension UITableView {
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
let numberOfSections = self.numberOfSections
let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: animated)
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.