且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何判断 UITableView 何时完成 ReloadData?

更新时间:2023-02-05 23:29:23

重新加载发生在下一个布局传递期间,这通常发生在您将控制权返回到运行循环时(例如,在您的按钮操作或任何返回之后).

The reload happens during the next layout pass, which normally happens when you return control to the run loop (after, say, your button action or whatever returns).

所以在表格视图重新加载后运行某些东西的一种方法是简单地强制表格视图立即执行布局:

So one way to run something after the table view reloads is simply to force the table view to perform layout immediately:

[self.tableView reloadData];
[self.tableView layoutIfNeeded];
 NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

另一种方法是使用 dispatch_async 安排布局后代码稍后运行:

Another way is to schedule your after-layout code to run later using dispatch_async:

[self.tableView reloadData];

dispatch_async(dispatch_get_main_queue(), ^{
     NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection:([self.tableView numberOfSections]-1)];

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

更新

经过进一步调查,我发现表格视图在从 reloadData返回之前将 tableView:numberOfSections:tableView:numberOfRowsInSection: 发送到其数据源代码>.如果委托实现了 tableView:heightForRowAtIndexPath:,则表视图也会在从 reloadData 返回之前发送(针对每一行).

UPDATE

Upon further investigation, I find that the table view sends tableView:numberOfSections: and tableView:numberOfRowsInSection: to its data source before returning from reloadData. If the delegate implements tableView:heightForRowAtIndexPath:, the table view also sends that (for each row) before returning from reloadData.

但是,表格视图在布局阶段之前不会发送 tableView:cellForRowAtIndexPath:tableView:headerViewForSection,默认情况下,当您将控制权返回给运行循环时会发生这种情况.

However, the table view does not send tableView:cellForRowAtIndexPath: or tableView:headerViewForSection until the layout phase, which happens by default when you return control to the run loop.

我还发现,在一个小型测试程序中,您问题中的代码会正确滚动到表格视图的底部,没有我做任何特别的事情(比如发送 layoutIfNeeded 或使用 dispatch_async).

I also find that in a tiny test program, the code in your question properly scrolls to the bottom of the table view, without me doing anything special (like sending layoutIfNeeded or using dispatch_async).