251

UIViewアニメーションを途中でキャンセルすることはできますか? または、CA レベルに落とす必要がありますか?

つまり、私はこのようなことをしました(おそらくアニメーション終了アクションも設定しています):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

しかし、アニメーションが完了し、アニメーション終了イベントを取得する前に、それをキャンセルしたい (短くしてください)。これは可能ですか?グーグルで調べてみると、何人かの人が同じ質問をしているのに答えがないことがわかります。

4

17 に答える 17

363

使用する:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
于 2010-03-19T06:53:32.753 に答える
115

私が行う方法は、エンドポイントに新しいアニメーションを作成することです. 非常に短い期間を設定し、+setAnimationBeginsFromCurrentState:メソッドを使用して現在の状態から開始するようにしてください。YES に設定すると、現在のアニメーションが短くなります。次のようになります。

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];
于 2009-05-08T21:46:03.680 に答える
63

特定のビューですべてのアニメーションを即座に停止する最も簡単な方法は次のとおりです。

プロジェクトを QuartzCore.framework にリンクします。コードの開始時に:

#import <QuartzCore/QuartzCore.h>

ここで、ビューのすべてのアニメーションを途中で停止したい場合は、次のように言います。

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

中央の行はそれ自体ですべて機能しますが、実行ループが終了するまで遅延があります (「再描画の瞬間」)。この遅延を防ぐには、示されているようにコマンドを明示的なトランザクション ブロックでラップします。これは、現在の実行ループでこのレイヤーに他の変更が行われていない場合に機能します。

于 2012-01-03T23:03:22.647 に答える
48

iOS 4 以降では、2 番目のアニメーションのオプションを使用してUIViewAnimationOptionBeginFromCurrentState、最初のアニメーションを短くします。

例として、アクティビティ インジケータを含むビューがあるとします。時間がかかる可能性のあるアクティビティの開始時にアクティビティ インジケーターをフェードインし、アクティビティが終了するとフェードアウトしたいとします。以下のコードでは、アクティビティ インジケーターが表示されたビューは と呼ばれactivityViewます。

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}
于 2011-08-11T08:30:54.467 に答える
42

アニメーションをキャンセルするには、UIView アニメーションの外で、現在アニメーション化されているプロパティを設定するだけです。これにより、どこでもアニメーションが停止し、UIView は定義した設定にジャンプします。

于 2010-06-19T17:09:34.700 に答える
12

ビュー プロパティの代わりに定数を変更して制約をアニメーション化する場合、iOS 8 では他の方法は機能しません。

アニメーションの例:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

解決:

制約の変更によって影響を受けるビューのレイヤーとそのサブレイヤーからアニメーションを削除する必要があります。

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}
于 2014-11-07T17:21:23.377 に答える
8

アニメーションをスムーズに一時停止/停止したいだけなら

self.yourView.layer.speed = 0;

出典:レイヤーツリーのアニメーションを一時停止する方法

于 2015-06-29T11:02:59.250 に答える
5

上記のいずれも解決しませんでしたが、これはUIView役に立ちました。アニメーションはプロパティをすぐに設定し、アニメーション化します。プレゼンテーション レイヤーがモデル (設定されたプロパティ) と一致すると、アニメーションが停止します。

「あなたが見えるところからアニメートしたい」という問題を解決しました(「あなた」はビューを意味します)。それが必要な場合は、次のようにします。

  1. QuartzCore を追加します。
  2. CALayer * pLayer = theView.layer.presentationLayer;

プレゼンテーション層に位置を設定する

を含むいくつかのオプションを使用しますUIViewAnimationOptionOverrideInheritedDuration

しかし、Apple のドキュメントはあいまいなので、使用時に他のアニメーションを本当にオーバーライドするのか、それとも単にタイマーをリセットするだけなのかはわかりません。

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

そして、それは今のところまともな解決策になるはずです。

于 2011-08-16T17:21:54.660 に答える
2

Stephen Darlington のソリューションの Swift バージョン

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()
于 2017-12-26T15:09:46.620 に答える
1

上記の方法でアニメーションをキャンセルしても、アニメーションはdidStopSelector実行されます。そのため、アニメーションによって駆動されるアプリケーションに論理状態がある場合、問題が発生します。このため、上記の方法では、UIViewアニメーションのコンテキスト変数を使用します。コンテキスト パラメータによってプログラムの現在の状態をアニメーションに渡すと、アニメーションが停止したときdidStopSelectorに、現在の状態とコンテキストとして渡された状態値に基づいて、関数が何かを実行するか、単に戻るかを決定できます。

于 2010-10-05T08:52:39.933 に答える
0

状態を元または最終状態に戻さずにアニメーションを一時停止するには:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
于 2015-12-03T21:43:48.233 に答える
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
于 2013-01-28T14:54:35.710 に答える