3

別々のアニメーション間の相互作用のように見えるものを見ています。この影響を排除するための提案をいただければ幸いです。

基本的に:ルートビューにボタン「a」を含むiPhoneアプリがあります。'a'をタップすると、ナビゲーションビューコントローラースタック上のビューがフリップアニメーションでプッシュされます。プッシュされたビューには、ビューをルートに戻すためのボタンがあります。

基礎となるコード:

- (IBAction)pushOneView{
TheAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight 
                    forView:delegate.navigationController.view cache:NO];
[delegate.navigationController 
            pushViewController:oneViewController animated:NO];
[UIView commitAnimations];

}

これはうまく機能しているようで、アニメーションは非常にスムーズです。

ルートビューには、サブビュー('panelView')と別のボタン'b'も含まれています。panelViewは、他の2つのサブビューのいずれかを表示できます。スピンアニメーションを使用して、これらのサブビュー間で「b」スワップをタップします。コード:

-(IBAction)swapPanels{
UIViewController *coming;
UIViewController *going;
float rotation;

if (self.aPanel.view.superview == nil) {
    coming = aPanel;
    going = bPanel;
    rotation = 3.14;
}
else {
    coming = bPanel;
    going = aPanel;
    rotation = -3.14;
}

// First half of spin
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
CGAffineTransform swirlTransform = CGAffineTransformMakeRotation(rotation);
panelView.transform = swirlTransform;
[panelView setAlpha:0.1];
[UIView commitAnimations];

// Finish spin
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
CGAffineTransform secondTransform = 
                        CGAffineTransformRotate(swirlTransform, rotation);
panelView.transform = secondTransform;
[panelView setAlpha:1];
[UIView commitAnimations];

// Swap the panels
[going.view removeFromSuperview];
[panelView insertSubview:coming.view atIndex:0];

}

これもうまくいくようです。交換可能な各パネルには、ピッカーといくつかのラベルが含まれています。

ただし、「b」遷移がその前に実行されている場合、「a」遷移は遅くてぎくしゃくすることに気付きます。つまり、アプリを起動して「a」を数回実行すると、スムーズに実行されます。次に、「b」を数回前後に動かします。次に、「a」をもう一度試してください...「a」はジャーキーになり、アプリが再起動するまでジャーキーのままになります。

これは100%再現可能です。シミュレーターを使用すると微妙ですが、デバイスでは非常に明白です。リークをテストしましたが、リークツールでは表示されません。アニメーションが「b」操作から削除された場合(アニメーションステップをコメントアウトするだけ)、「b」サブビュースワップが実行された後、「a」への影響は観察されません。ピッカーを交換可能なパネルペン先から取り外すと、同様にその影響はなくなります。'a'アニメーショントランジションがキャッシュに設定されている場合、'b'の後は途中で途切れることはありませんが、アニメーションを無視しているように見えます。単にビューを入れ替えるだけです(これは知覚の問題かもしれません)。

よくわからない場合:これらの個別の操作を同時にトリガーしていません。「b」が実行されて完了した後のアニメーション「a」は、「b」が実行されたことがない場合と同じではありません。アニメーションの後に行うべきクリーンアップはありますか?サブビュー交換コードに欠陥がありますか?または...?

提案を事前に感謝します。

4

2 に答える 2

8

「b」セクションに 2 つのオーバーラップするアニメーションがあります。begin / commit ブロックを使用してアニメーションを作成すると、アニメーションはバックグラウンド スレッドに渡されて実行されます。「b」セクションでは、連続する必要がある 2 つのアニメーションが、実際にはほぼ同時に開始されています。これにより、表示されているような奇妙な動作が発生する可能性があります。

次のようなコードを使用して、最初のアニメーションでコールバックをデリゲート メソッドに追加することをお勧めします。

[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(rotationAnimationFinished:finished:context:)];

'b' の最初のアニメーション ブロック内 (「スピンの前半」部分)。次に、クラス内でコールバック メソッドを定義する必要があります。この場合は、

- (void)rotationAnimationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context;

スピン アニメーションの最初の部分が終了したときに呼び出されるデリゲート メソッド内に、「b」メソッドの残りのコードを配置します (すべて「Finish spin」コメントの後にあります)。

これらのアニメーションを分離することで、見ている奇妙さを防ぐことができます。

于 2009-05-09T03:20:01.100 に答える