1

セグエを使用して、別の画面に切り替えるナビゲーション バーに UIBarButtonItem があります。この別の画面の初期化には時間がかかるため、UIActivityIndi​​cator を UIBarButtonItem に配置して、タップが登録され、iPad がアクションの実行中であることを示したいと考えました。

私のアプローチは、UIActivityIndi​​cator が押された後に UIBarButtonItem に追加し、次に を呼び出しperformSegueWithIdentifier:viewDidLoad2 番目のビューのメソッドで初期化を呼び出しに入れることでした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];
    }

2 番目の画面での初期化:

- (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 が一瞬表示され、最後にセグエ アニメーションが表示されて 2 番目の画面が表示されます。

何か案が?どうもありがとう!

編集:おそらく問題への追加は、初期化がいくつかのUIKitのものを行うことです:セマフォを使用しようとすると、UITextViewメソッドで初期化がBAD ACCESSでダンプします。これは、「get_main_queue」ではなく「get_global_queue」で実行されるためだと思います。

もう一度編集:いいえ。Apple ドキュメントで発表されているように、「get_main_queue」を使用するとデッドロックが発生します。したがって、質問は要約すると

「スピナーを実行しながらバックグラウンドで UIView を作成するにはどうすればよいですか?」

4

2 に答える 2

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 ファイルを使用している場合は、申し訳ありません。

于 2012-11-01T12:26:35.357 に答える
1

1 つの問題は、2 番目の画面でメソッドを使用dispatch_syncしていることだと思います。ブロックが完了するまでスレッドをブロックします。代わりに変更してみてください。viewDidLoaddispatch_sync// do initialization heredispatch_async

私があなただったら、もう 1 つ検討したいことはUIActivityIndicator、最初の画面ではなく、2 番目の画面の一部として を表示することです。そうすれば、ビューがコストのかかる操作を終了した後、2 番目の画面でもそれを閉じることができます。もちろん、これは、これらの操作が完了する前にビューが実際に表示できることを前提としています。

于 2012-11-01T05:09:07.650 に答える