私はこのコードを実行しています...
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGAffineTransform settingsTransform = CGAffineTransformMakeTranslation(self.settingsView.frame.size.width, 0);
CGAffineTransform speedTransform = CGAffineTransformMakeTranslation(-self.speedView.frame.size.width, 0);
self.settingsView.transform = settingsTransform;
self.speedView.transform = speedTransform;
} completion:nil];
しかし、ビューを実行すると、正しい方向に半分の位置にスライドする前に、ビューが変換の半分を反対方向にジャンプします。
アニメーションの持続時間を5秒に落としましたが、最初のジャンプは瞬間的で、変換の半分が間違った方向に行われました。
このコードを使用してアニメーションを戻すと...
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.settingsView.transform = CGAffineTransformIdentity;
self.speedView.transform = CGAffineTransformIdentity;
} completion:nil];
まったく同じことを行います。
結果は、最初に間違った方向に変換の半分をジャンプするため、最終的な動きは希望の変換の半分になります。
なぜこれが起こっているのか本当に分かりませんか?
何か案は。
::編集::
可能性のあるあいまいさを解消する。
私はこれらの見解を彼らがいる場所に「跳ね返る」ようにしようとしているのではありません。私がアニメーション化しているビューは、画面の端にあるコントロールパネルのようなものです。ユーザーが「移動」を押すと、ビューがスライドして邪魔になります。ユーザーが「停止」ボタンを押すと、パネルがスライドしてビューに戻ります。
少なくとも彼らは昔はそうだった。自動レイアウトを有効にしたので(アプリの他の部分に必要です)、ビューのフレームを変更するだけでは済まないため、変換ルートに進みました。
この効果は、ビューをビューコントローラーに貼り付け、アニメーションを実行するボタンで確認できます。
ありがとう
OK、WWDCビデオをもう一度見たとき、AutoLayoutを使用するときに最初に行う必要があることの1つは、setFrameの呼び出しを削除することだと述べています。
画面が複雑なため、自動レイアウトを完全に削除し、フレームの位置を使用して画面内でビューを移動しています。
ありがとう
私はまったく同じ問題を抱えていたので、ここに私が思いついた解決策があります。
CGAffineTransform transform = CGAffineTransformMake(1, 0, 0, 1, translation.x, translation.y);
[UIView animateWithDuration:0.25 animations:^{
_assetImageView.transform = transform;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
したがって、[self.view layoutIfNeeded]を呼び出します。 animateブロックの内側。これがないと、あなたと同じ問題が発生し、最初に負の並進距離をジャンプしてから、そこから正しい位置にアニメートします。これをビューコントローラから呼び出しているので、selfはUIViewControllerのサブクラスです。あなたの場合、「self.view」は存在しないかもしれませんが、私はあなたがアイデアを得ることを望みます。
ここでの解決策はどれも私にとってうまくいきませんでした...私のアニメーションは常にスキップします。 (別のアニメーションの最後であった場合を除いて、ヒント)。
一部詳細:
これを行っていたビューには、一連のスケールがあり、すでにスタックに変換されています。
ソリューション:
キーフレームアニメーションを実行します。最初のキーが非常に短く、基本的に、最後のアニメーションで設定する必要のある変換を再適用します。
UIView.animateKeyframesWithDuration(0.4, delay: 0.0, options: [.CalculationModeCubic], animations: { () -> Void in
//reset start point
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.01, animations: { () -> Void in
self.element.transform = initialTransform
})
UIView.addKeyframeWithRelativeStartTime(0.01, relativeDuration: 0.99, animations: { () -> Void in
self.element.transform = finalTransform
})
}, completion: nil)
私はこの問題についてApple Technical Supportに質問し、この応答を得たので、それはバグです。
iOS 8は現在、UIKitアニメーションの既知のバグを示しており、変換アニメーションは間違ったfromValueを取得します(主にアニメーションオブジェクトの位置に影響し、アニメーションの開始時に予期せず「ジャンプ」するように見えます)。
[...]
潜在的な修正が提供されるまでの回避策は、Core Animation APIにドロップダウンしてアニメーションをコーディングすることです。
アンドレアスの回答の改良版は次のとおりです。主な違いは、キーフレームを1つだけ指定して、コードを少なくできることです。
UIView.animateKeyframes(withDuration: animationDuration, delay: 0.0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1.0, animations: {
animatedView.transform = newTransform
})
}, completion: nil)
このアニメーションが発生する前に、settingsViewまたはspeedViewに既に変換が適用されていますか?
これらのビューの変換が恒等変換(別名CGAffineTransformIdentity、別名変換なし)でない場合、それらの.frameプロパティにアクセスできません。
UIViewsのフレームプロパティは、変換が適用されている場合は無効です。代わりに「境界」を使用してください。
2番目のアニメーションは、最初のアニメーションの現在の状態(終了したかどうかに関係なく)から発生させたいので、2番目のアニメーションを設定するときにUIViewAnimationOptionLayoutSubviews
オプションを使用することをお勧めします。
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionLayoutSubviews
animations:^{
self.settingsView.transform = CGAffineTransformIdentity;
self.speedView.transform = CGAffineTransformIdentity;
} completion:nil];
以下は、シンプルなビューコントローラーテンプレートを使用してテストするために使用したコードのサンプルです。
myviewcontroller.m:
- (void)viewDidLoad
{
[super viewDidLoad];
self.animatedView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 160, 80)];
self.animatedView.backgroundColor = [UIColor yellowColor];
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionLayoutSubviews
animations:^{
CGAffineTransform settingsTransform = CGAffineTransformMakeTranslation(self.animatedView.frame.size.width, 0);
self.animatedView.transform = settingsTransform;
}
completion:nil];
self.buttonToTest = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.buttonToTest.frame = CGRectMake(90, 20, 80, 40);
[self.buttonToTest setTitle:@"Click Me!" forState:UIControlStateNormal];
[self.buttonToTest addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
// set-up view hierarchy
[self.view addSubview:self.buttonToTest];
[self.view addSubview: self.animatedView];
}
- (void) buttonClicked
{
[UIView animateWithDuration:.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionLayoutSubviews
animations:^{
self.animatedView.transform = CGAffineTransformIdentity;
}
completion:nil];
}
私はこの問題を抱えており、次の方法で解決しました:
お役に立てれば。