2011-11-06 4 views
5

別のスレッドで実行されているすべてのアニメーションを停止し、私はそうのようにそれをやっている:は、私が3秒間隔で右互いの後に飛び出るのアイテムとメニューを持って

for(UIButton *menuItem in menuItems){ 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{ 
     [menuItem setAlpha:1.0]; 
    }        
} 

はそれがアニメーションを停止することが可能です途中で(例えばボタンに触れたとき)? 私はすべてをアルファ1.0に設定しようとしましたが、期待どおりにスレッドは実行し続けてアイテムを再び表示します。

任意のアイデアに感謝します:)
Shai。

+0

あなたの質問に無関係ですが、今はUIKitスレッドセーフですか? – Rog

+0

どういう意味なのか分かりません:> –

+0

iOS5で何か変わっていない限り(そして私はそうは思わない)、あなたはメインスレッドを通してあなたのUIを更新することになっています。ディスパッチキューがバックグラウンドスレッドでUIを更新しているため、アプリで不安定な問題が発生する可能性があります。ここには、公式のドキュメント(ページの一番下)からのものがあります。http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKit_Framework/Introduction/Introduction.html#//apple_ref/doc/uid/TP40006955 -CH1-SW1 – Rog

答えて

3

アニメーションは、delay:を設定したUIViewブロックベースのアニメーションを使用して行うことができます。スレッドは心配していません。

これらのアニメーションは、ブロックベースのアニメーションUIViewAnimationOptionBeginFromCurrentStateを設定して開始することで中断できます。

これは、アニメーションの現在の位置が何であるかは関係ありませんので、これは問題ありません。オブジェクトを移動する場合は、オブジェクトの現在の状態を保持するview.layer.presentationLayerを照会することによって現在の位置を取得できます。これを行うには、QuartzCoreフレームワークをインポートする必要があります。これはまた、あなたが保留中またはアクティブになっているアニメーションの終点にどのような見解を持っていても、それが聞こえるようになるメソッドremoveAllAnimationsを提供します。

+0

問題は私がアルファをプレイしているだけではなく、私はCocoDenshionでもサウンドを再生しています。あなたの方法を試して、それが機能するかどうかを見てみましょう。ありがとうございました:) –

+0

次のコードは、何らかの理由で遅延の代わりにすべてのアイテムを同時に表示しています。http://pastebin.com/dVEzCEWr –

+0

完了ブロックはアニメーションが終了するまで実行されません。各アニメーションが設定される前に、forループでiをインクリメントします。私は完成ブロックであなたのサウンドを演奏できると付け加えようとしていました。アニメーションが中断された場合、BOOLパラメータはNOになり、サウンドを再生しないことを知っています。 – jrturton

0

多分、あなたはthisという回答で回答を見つけるでしょうし、あなたは他の方法であなたのものをやるでしょう。

+0

このコメントは、主にdispatch_asyncアプローチが正しい方法ではないことを示しています。私たちが[NSThread performSelector]について話している場合を除き、実際に代替案を提示していません。既に予定されているアニメーション)。 –

+1

また、私はあなたの時間を感謝します - 私は文とリンクは答えと見なされないと思う。次回はコメントが必要です。もう一度、あなたの時間に関係なく、ありがとう。 –

+0

問題ありません。私は遅延とキャンセルされたブロックhttps://gist.github.com/955123のためのNSObjectカテゴリのこの要点のソースコードを見つけます。ブロックインスタンスを作成するためにそれらのメソッドを使用し、それらを保存しようとするならcancelBlockを呼び出すことができます: 。 –

1

既にスケジュールされているアニメーションを停止することはできません。しかし、ボタンが既に押されたかどうかを示すフラグBOOLを使ってインスタンス変数を設定することができます。

たとえば、ボタンのターゲットがbuttonTappedのメソッドであるとします。

フラグをNOに初期化します。

- (id)init { 
    if (self = [super init]) { 
     buttonAlreadyTapped = NO; 
    } 

    return self; 
} 

ボタンのターゲットでは、フラグをYESに設定します。

- (void)buttonTapped { 
    self.buttonAlreadyTapped = YES; 
} 

そして唯一のフラグがNOある場合alphaを変更します。

for (NSInteger i = 1; i <= [menuItems count]; i++) {   
    UIButton *menuItem = [menuItems objectAtIndex:i-1]; 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{ 
     if (!self.buttonAlreadyTapped) { 
      menuItem.alpha = 1.0f; 
     } 
    }); 
} 

UIKitにメッセージを送信し、 常には、メインスレッド上で行われるべきであることに注意してください。

for (NSInteger i = 1; i <= [menuItems count]; i++) {   
    UIButton *menuItem = [menuItems objectAtIndex:i-1]; 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{ 
     if (!self.buttonAlreadyTapped) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       menuItem.alpha = 1.0f; 
      }); 
     } 
    }); 
} 
+0

私はすでにそれをやっているが、それは本当に役立たない。私は6つのメニュー項目を1つずつ表示しています。ユーザーがそれらのいずれかをクリックすると、入力アニメーションを停止してそれらをすべて表示し、キュー内のアニメーションをキャンセルします。 –

+0

+1メインスレッドのヒント、それを知らなかった(dispatch_afterのdispatch_async)。ありがとうございました:) –

関連する問題