我有一个根视图控制器,它为模态视图控制器提供标准动画(模态视图控制器从下到上显示)。
我们将此视图命名为控制器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个项目,则需要几秒钟,然后才开始演示动画。
太慢了。所以我的问题是解决这个问题的最佳方法是什么?
答案 0 :(得分:2)
好吧,您可以在后台主题
上加载项目列表- (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];
});
});
}
答案 1 :(得分:1)
在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];
}
答案 2 :(得分:1)
问题是因为我试图从- (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及更高版本中引起,那就太棒了。
答案 3 :(得分:0)
您可以在上一个视图控制器中对项目列表收费,并将其设置为新的:
- (void)openModalViewController {
MyModalTableViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myModalScreen"];
vc.itemlist = self.itemlist;
[self presentViewController:vc animated:YES];
}