且构网

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

如何判断 UITableView 何时完成了 ReloadData?

更新时间:2023-02-05 23:24:39

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

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).

因此,在 table view 重新加载后运行某些东西的一种方法是强制 table view 立即执行布局:

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).