在UIBarButtonItem按下之后,在segue导航期间显示UIActivityIndi​​cator

时间:2012-10-18 19:37:23

标签: objective-c spinner uibarbuttonitem uiactivityindicatorview uistoryboardsegue

我在导航栏中有一个UIBarButtonItem,它使用segue切换到另一个屏幕。这个其他屏幕需要一些时间来初始化,我想在UIBarButtonItem上放置一个UIActivityIndi​​cator来显示已经注册的tap,并且iPad正忙于执行该操作。

我的方法是在按下UIBarButtonItem之后向其添加UIActivityIndi​​cator,然后调用performSegueWithIdentifier:,并在第二个视图的viewDidLoad方法中将初始化放入dispatch_sync()呼叫。你可以猜测它不起作用......为什么?

第一个屏幕上的IBAction:

- (void)tappedEdit: (UIBarButtonItem *)editButton {
    // put activity indicator somewhere
    UIActivityIndicatorView *indicator;
    indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    indicator.frame = CGRectMake (200, 5, 50, 50);
    [self addSubview: indicator];
    [indicator startAnimating];
    // follow segue
    [self performSegueWithIdentifier: SegueShowDesignMode sender: editButton];
    }

第二个屏幕上的初始化:

- (void)viewDidLoad {
    [super viewDidLoad];
    // put costly operations into another queue to free main queue for activity indicator
    dispatch_sync (dispatch_get_global_queue (0, 0), 
                   ^{ // do initialization here
                   });
}

这样做的结果是UIBarButtonItem在执行初始化时保持轻敲,然后UIActivityIndi​​cator快速可见,最后显示segue动画,显示第二个屏幕。

有什么想法吗?非常感谢!

编辑:可能是问题的另一个问题是初始化会执行一些UIKit的东西:当我尝试使用信号量时,初始化转储在某些UITextView方法中带有BAD ACCESS。我想这是因为它运行在一些'get_global_queue'而不是'get_main_queue'上。

再次编辑:嗯,不。使用'get_main_queue'会导致死锁,正如Apple文档中所宣布的那样。所以问题归结为

“如果还在运行微调器,我怎么能创建背景UIView(很多!)?”

2 个答案:

答案 0 :(得分:1)

我认为一个问题是您在第二个屏幕中的dispatch_sync方法中使用了viewDidLoaddispatch_sync将阻止您的线程,直到// do initialization here的块完成为止。请尝试将其更改为dispatch_async

如果我是你,我会考虑做的另一件事是让UIActivityIndicator显示为第二个屏幕的一部分,而不是第一个屏幕。这样,第二个屏幕也可以在您的视图完成昂贵的操作后将其关闭。当然,这假设视图可以在这些操作完成之前实际显示。

答案 1 :(得分:1)

如果您使用的是故事板

ButtonBarItem.h

 #import "CheckWifi.h"

    interface LoadingViewController : UIViewController 

    -(IBAction)BarItemPressed:(id)sender;

ButtonBarItem.m:

-(IBAction)BarItemPressed:(id)sender {LoadingViewController *DIS = [self.storyboard instantiateViewControllerWithIdentifier:@"CheckWifi"];
DIS.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:DIS animated:YES];}

LoadingViewController.h:

 @interface LoadingViewController : UIViewController {

    IBOutlet UIActivityIndicatorView *spinner

    }

-(IBAction)StopAnimating;

@end

LoadingViewController.m:

-(void)ViewDidLoad {

spinner.hidden = NO;

}

-(IBAction)StopAnimating {

    spinner.hidden = YES;

    }

如果您正在使用XIB文件,那么我无法帮助您,抱歉。