动画视图控制器并同时在 table 视图中重新加载数据

Animate view controller and reload data in table view at the same time

我有一个根视图控制器,它以标准动画呈现模态视图控制器(模态视图控制器从下到上出现)。

让我们将此视图控制器命名为 MyRootViewControllerMyModalTableViewController

问题是如果 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 及更高版本上出现,那就太好了。