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

时间:2015-02-13 10:29:02

标签: ios objective-c uitableview uianimation presentviewcontroller

我有一个根视图控制器,它为模态​​视图控制器提供标准动画(模态视图控制器从下到上显示)。

我们将此视图命名为控制器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个项目,则需要几秒钟,然后才开始演示动画。

太慢了。所以我的问题是解决这个问题的最佳方法是什么?

4 个答案:

答案 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];
}