objective-c - 如何判断 UITableView 何时完成 ReloadData?

我正在尝试在 UITableView 执行完 [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。

我用的很奇怪:

[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;

当我在 cellForRowAtIndexPath 中执行完全相同的 NSLogs 时,我得到 Sections = 1 和 Row = 8; (8对)

最佳答案

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

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

[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 安排布局后代码稍后运行:

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

更新

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

然而,表格 View 直到布局阶段才发送 tableView:cellForRowAtIndexPath:tableView:headerViewForSection,这在您将控制权返回给运行循环时默认发生.

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

https://stackoverflow.com/questions/16071503/

相关文章:

ios - 带有隐藏 UIView 的自动布局?

ios - 何时使用 dequeueReusableCellWithIdentifier 与 deq

ios - 如何在 UITableViewCell 之间添加间距

objective-c - 从 NSString 中删除除数字之外的所有数字

ios - 更改 UIImageView 的图像时淡入淡出/溶解

ios - Xcode 调试器不打印对象并显示 nil,当它们不是时

ios - UIButton 标题文本颜色

objective-c - 仅在 iOS 7 上运行时,Storyboard 原型(prototyp

ios - 错误 : _handleNonLaunchSpecificActions in iOS9

ios - 在 iOS 6 中以编程方式打开 map 应用