2009-03-03 13 views
3

私はUITableViewControllerを持っています。これはRootViewControllerです。 XIBにはテーブルビューしかありません。私はIBを介してUIActivityIndi​​catorを追加し、IBOutletを作成しました。私はプログラムによってRootViewControllerに削除ボタン付きのツールバーを追加しました。ユーザーがツールバーの削除ボタンをクリックすると、画面中央にインジケータが表示されます。以下の方法はデータベースからデータを削除しますが、これは非常に高速です。私は何かが起こっていることをユーザーに知らせたい。 sleep()を使わないで以下のコードを実行すると、速くなり、インジケーターが表示されません。しかし何らかの理由でいくつか、私はとにかくインジケータを見ていないよ。私はsleep()ブロックを再描画すると思いますか?私が睡眠()と最後の2つのラインを取る場合、私は指標を参照してください、もちろんそれは決して遠ざかりません。また、ウィンドウの左上にも表示されます。UIActivityIndi​​catorをx秒間表示する

インジケータが少なくとも1/2秒間表示されるように、以下のコードをどのようにして取得するのですか?

インジケータをウィンドウの中央に揃えるにはどうすればよいですか?

[self.navigationController.view addSubview:activityIndicator]; 
[activityIndicator startAnimating]; 
[activityIndicator setNeedsDisplay]; 

//do something which might happen really fast 

sleep(1); //create illusion 
[activityIndicator stopAnimating]; 
[activityIndicator removeFromSuperview]; 

答えて

6

イベントを処理して実行ループに戻すまで、スピナーは回転を開始しません。この周りの方法は、あなたのために物事を完了するために実行ループを求めることです。ここで

は、私が何を意味するかの例です:

- (IBAction)deleteAction:(id)sender { 
    [self.navigationController.view addSubview:activityIndicator]; 
    [activityIndicator startAnimating]; 

    // Spinner won't start spinning until we finish processing this event, so 
    // we're just going to schedule the rest of what we need to do. 

    // doDelete: will run when the main thread gets its next event. 
    [self performSelectorOnMainThread:@selector(doDelete:) 
          withObject:record 
         waitUntilDone:NO]; 

    // removeSpinner: will run in at least one second, but will wait if 
    // another event (like the doDelete: one) is in the middle of running. 
    [self performSelector:@selector(removeSpinner:) 
       withObject:activityIndicator 
       afterDelay:1.0]; 
} 
- (void)doDelete:(id)record { 
    [record delete]; // or whatever it is you need to do 
} 
- (void)removeSpinner:(UIActivityIndicator*)activityIndicator { 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 
} 

注:そこに「スリープ」期間中に他のタッチを処理することからそれを停止することが保証されて、このコードには何もいないので、あなたが出て、他のロックを確認してください何とかイベント。

+0

恐ろしい!ありがとう。ウィンドウの中央にインジケータを表示させる方法があるかどうか知っていますか?左上隅にネストされているように見えます。 – 4thSpace

+0

activityIndi​​cator.center = CGPointMake(self.navigationController.view.frame.size.width/2、self.navigationController.view.frame.size.height/2); –

+0

再びブレントに感謝します。素晴らしいもの。 – 4thSpace

0

問題は、あなたがあなたのことをやっている間、メイン実行ループが実行されていないことです。アクティビティインジケータを表示するには、アニメーションを更新できるようにメイン実行ループを実行する必要があります。意図した動作を得るには、別のスレッドで非同期にデータベース操作を行う必要があります。

+0

APIでマルチスレッドが可能ですか? – 4thSpace

+0

うわー。私は "活動を示すインジケーター"のようなものを考えていました。 しかし、なぜそれはまったく同じように動作しないように設計されていたのですか?このオブジェクトの "全部の活動"を*全体*の点ではありませんか? – Bonnie

1

Adamが述べたように、作業(この場合はDelete操作)がバックグラウンドスレッドで行われない限り、スピナーは表示されません。これは私がブレントの初期コードに基づいて動作させたコードです。バックグラウンドスレッドで作業を行う関数を呼び出すように変更し、終了時にメインスレッドを使用してスピンを削除しました。

- (void)removeSpinner:(id)record { 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Thank You" message:@"Thanks for your feedback!" 
                           delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 

    // return to feedings tab 
    tabBarController.selectedIndex = 0; 
} 


- (void)doFeedback:(id)record { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    int j; 
    for (int i = 0; i < 1000000000; i++) { 
     j = j + i; 
    } 
    [self performSelectorOnMainThread:@selector(removeSpinner:) withObject:nil waitUntilDone:NO]; 

    [pool release]; 
} 


- (IBAction)handleSend {   
    [self.view addSubview:activityIndicator]; 
    [activityIndicator startAnimating]; 

    // Spinner won't start spinning until we finish processing this event, so 
    // we're just going to schedule the rest of what we need to do. 
    // doFeedback: will run when the main thread gets its next event. 
    [self performSelectorInBackground:@selector(doFeedback:) withObject:nil]; 
} 
0

[self.navigationController.view addSubview:activityIndi​​cator]。 [activityIndi​​cator startAnimating];

[self performSelector:@セレクタ(removeSpinner :) withObject:activityIndi​​cator afterDelay:5.0];

関連する問題