动画视图控制器并同时在 table 视图中重新加载数据
Animate view controller and reload data in table view at the same time
我有一个根视图控制器,它以标准动画呈现模态视图控制器(模态视图控制器从下到上出现)。
让我们将此视图控制器命名为 MyRootViewController
和 MyModalTableViewController
。
问题是如果 MyModalTableViewController
出现时重新加载数据,动画就会停止。
例如:
- (void)openModalViewController {
MyModalTableViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myModalScreen"];
[self presentViewController:vc animated:YES];
}
在 MyModalTableViewController
中我有下一个代码:
- (void)viewDidLoad {
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
}
// ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell * cell = [tableView dequeReusableCellWithIdentifier:@"myCell"];
cell.item = self.itemList[indexPath.row];
return cell;
}
因此,当 MyModalTableViewController
从故事板加载时,它会加载 itemList
并在 UITableView
上显示。演示动画仅在 UITableView
完成加载数据时开始。我猜是因为动画和数据重新加载在同一个线程中工作。因此,如果我要显示 10000 个项目,则需要几秒钟,然后才开始演示动画。
太慢了。所以我的问题是解决这个问题的最佳方法是什么?
在MyModalTableViewController
中添加方法loadData
- (void)loadData {
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
[self.tableView reloadData];
}
然后使用`presentViewController
的完成块
[self presentViewController:vc animated:YES completion:^{
[vc loadData];
}
嗯,你可以在后台线程加载你的项目列表
- (void)viewDidLoad {
//background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//load data
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
//main thread
dispatch_async(dispatch_get_main_queue(), ^{
//reload table
[self.tableView reloadData];
});
});
}
可以在之前的view controller中对itemlist进行充电,然后设置为新的:
- (void)openModalViewController {
MyModalTableViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myModalScreen"];
vc.itemlist = self.itemlist;
[self presentViewController:vc animated:YES];
}
问题是因为我试图从 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
委托方法中呈现视图控制器。
此委托方法未在主线程中调用,这就是动画运行缓慢的原因。看起来太奇怪了,因为在 iOS 7 我没有遇到这样的问题。它只发生在 iOS 8 及以后。
我在这个 SO 主题中发现了同样的问题:Slow presentViewController performance
所以解决方案是像下面这样实现委托:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
__block UIViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myVC"];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:vc animated:YES completion:nil];
});
}
我查看了 Apple 文档,但没有发现此委托方法调用不在主线程中的通知:https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:
所以,如果有人能解释为什么这个问题只在 iOS 8 及更高版本上出现,那就太好了。
我有一个根视图控制器,它以标准动画呈现模态视图控制器(模态视图控制器从下到上出现)。
让我们将此视图控制器命名为 MyRootViewController
和 MyModalTableViewController
。
问题是如果 MyModalTableViewController
出现时重新加载数据,动画就会停止。
例如:
- (void)openModalViewController {
MyModalTableViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myModalScreen"];
[self presentViewController:vc animated:YES];
}
在 MyModalTableViewController
中我有下一个代码:
- (void)viewDidLoad {
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
}
// ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell * cell = [tableView dequeReusableCellWithIdentifier:@"myCell"];
cell.item = self.itemList[indexPath.row];
return cell;
}
因此,当 MyModalTableViewController
从故事板加载时,它会加载 itemList
并在 UITableView
上显示。演示动画仅在 UITableView
完成加载数据时开始。我猜是因为动画和数据重新加载在同一个线程中工作。因此,如果我要显示 10000 个项目,则需要几秒钟,然后才开始演示动画。
太慢了。所以我的问题是解决这个问题的最佳方法是什么?
在MyModalTableViewController
中添加方法loadData
- (void)loadData {
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
[self.tableView reloadData];
}
然后使用`presentViewController
的完成块 [self presentViewController:vc animated:YES completion:^{
[vc loadData];
}
嗯,你可以在后台线程加载你的项目列表
- (void)viewDidLoad {
//background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//load data
self.itemList = [[MyData sharedInstance] itemList]; // self.itemList is NSArray
//main thread
dispatch_async(dispatch_get_main_queue(), ^{
//reload table
[self.tableView reloadData];
});
});
}
可以在之前的view controller中对itemlist进行充电,然后设置为新的:
- (void)openModalViewController {
MyModalTableViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myModalScreen"];
vc.itemlist = self.itemlist;
[self presentViewController:vc animated:YES];
}
问题是因为我试图从 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
委托方法中呈现视图控制器。
此委托方法未在主线程中调用,这就是动画运行缓慢的原因。看起来太奇怪了,因为在 iOS 7 我没有遇到这样的问题。它只发生在 iOS 8 及以后。
我在这个 SO 主题中发现了同样的问题:Slow presentViewController performance
所以解决方案是像下面这样实现委托:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
__block UIViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myVC"];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:vc animated:YES completion:nil];
});
}
我查看了 Apple 文档,但没有发现此委托方法调用不在主线程中的通知:https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didSelectRowAtIndexPath:
所以,如果有人能解释为什么这个问题只在 iOS 8 及更高版本上出现,那就太好了。