如何判断UITableView完成ReloadData的时间? [英] How to tell when UITableView has completed ReloadData?
问题描述
执行[self.tableView reloadData]
我原来有
[self.tableView reloadData]
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是异步的,因此滚动不会发生,因为self.tableView
,[self.tableView numberOfSections]
和[self.tableView numberOfRowsinSection
都为0.
But then I read that reloadData is asynchronous, so the scrolling doesn't happen since the self.tableView
, [self.tableView numberOfSections]
and [self.tableView numberOfRowsinSection
are all 0.
谢谢!
我使用的是什么奇怪的东西
What's weird is that I am using:
[self.tableView reloadData];
NSLog(@"Number of Sections %d", [self.tableView numberOfSections]);
NSLog(@"Number of Rows %d", [self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1);
在控制台中,它返回Sections = 1,Row = -1;
In the console it returns Sections = 1, Row = -1;
当我在cellForRowAtIndexPath
中执行完全相同的NSLogs时,我得到Sections = 1和Row = 8; (8对)
When I do the exact same NSLogs in cellForRowAtIndexPath
I get Sections = 1 and Row = 8; (8 is right)
推荐答案
重新加载会在下一次布局传递期间发生,通常是在您将控制权返回到运行循环时发生(例如,在您执行按钮操作或返回任何内容之后).
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
或使用
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
).
这篇关于如何判断UITableView完成ReloadData的时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!