4

我有一个 ViewController 需要时间来加载它的视图。当我运行 Instruments 时,我从主屏幕看到,如果我点击将视图控制器推送到堆栈上的图标,它的一半是布局视图,一半是获取视图的数据。当按下按钮将 LongRunningViewController 推入堆栈时,我尝试添加一个活动指示器以显示在按钮上方的主屏幕上。所以我基本上是这样做的:

- (IBAction)puzzleView:(id)sender {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.activityIndicator startAnimating];
    });

    PuzzleViewController *detailViewController = [[[PuzzleViewController alloc] init] autorelease];
    [self.navigationController pushViewController:detailViewController animated:YES];
    [self.activityIndicator stopAnimating];
}

按下按钮时主屏幕滞后,然后加载视图。我试图在另一个屏幕准备被推送时显示活动指示器(或者至少我认为它是这样工作的)。但是,活动指示器不显示。我想知道这是否可以做到?还是其他应用程序推送他们的 ViewController,然后在那个屏幕上,他们有显示不同资源加载的活动指示器?

4

1 回答 1

9

当您说获取视图数据需要时间时,我假设您的意思是在PuzzleViewController某处做一些不平凡的事情,例如viewDidLoad.

所以假设它在viewDidLoad. 然后你可以这样做:

-(void)viewDidLoad
{
  [self.activityIndicator startAnimating];
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
    {
         //do something expensive
         [self doSomethingExpensive];

         //dispatch back to the main (UI) thread to stop the activity indicator
         dispatch_async(dispatch_get_main_queue(), ^
         {
            [self.activityIndicator stopAnimating];
         });
    });
}

这意味着昂贵的操作将被放在后台线程上,并且不会阻塞视图控制器的加载/显示。

这种方法在用户按下按钮时立即显示请求的视图,并在该屏幕上显示进度。我认为这种方式比在呈现视图之前加载内容时显示活动视图更常见。这也为您赢得了更多时间;您的长时间操作可以在过渡动画期间在后台运行!

你的活动视图没有显示你正在做的方式的原因是你在 UI 线程上做这一切;从主队列使用dispatch_async主队列不会完成任何事情,因为在运行循环完成之前,您的块将没有机会运行。

于 2012-09-24T21:47:03.163 回答