如何判断 UITableView 何时完成 ReloadData? [英] How to tell when UITableView has completed ReloadData?

查看:23
本文介绍了如何判断 UITableView 何时完成 ReloadData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 UITableView 完成执行后滚动到底部 [self.tableView reloadData]

I am trying to scroll to the bottom of a UITableView after it is done performing [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.

谢谢!

奇怪的是我正在使用:

[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];
});

更新

经过进一步调查,我发现表格视图在从 reloadDatatableView: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).

这篇关于如何判断 UITableView 何时完成 ReloadData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆