加载ViewController时显示活动指示器

时间:2012-09-24 21:36:34

标签: iphone

我有一个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,然后在该屏幕上,他们有活动指示器显示其不同资源的加载?

1 个答案:

答案 0 :(得分:9)

当你说获取视图的数据需要时间时,我认为你的意思是PuzzleViewControllerviewDidLoad之类的地方做了一件非常重要的事情。

所以我们说它在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到主队列将无法完成任何事情,因为在运行循环完成之前,您的块将无法运行。