UIView
変換プロパティのアニメーションがiOS8とiOS6/7で異なって見える理由を見つけようとしています。
簡単な例として、iOS 8より前:
myView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, 1.57);
[UIView animateWithDuration:5 animations:^{
myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0);
}];
期待どおりの結果が得られ、「myView」は90度回転して下に移動しますが、iOS8では、翻訳がアニメーション化されると、説明が見つからないポイントから開始します(アニメーションが壊れます)。
誰かがそれの説明を知っていますか?前もって感謝します!
CGAffineTransformIdentityは、ios7とios8で動作が異なります。これは、自動レイアウトとサイズクラスに関係しています。解決策は、ios7のアニメーションと競合する制約を削除することです。
// solve the constraint-animation problem
if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) {
// iOS7 remove constraints that conflict with animation
if (self.centerYAlignment != nil) {
self.view.removeConstraint(self.centerYAlignment) //is an IBOutlet
}
} else {
// iOS8 constraint animations are fine
}
IOS7でもぎくしゃくした回転変換に問題がありました。回転したビューをコンテナ内にネストし、回転したビューを中央に配置することで、これを解決しました。
理由はiOS8のバグだけだと思いますが、代わりにCAAnimationを使用しており、iOS8でも期待どおりに動作します。
スケーリングでも同じ問題が発生しています。回転でも同じかもしれないと思います。これを試していただけませんか?
myView.transform = CGAffineTransformConcat(myView.transform , CGAffineTransformMakeRotate(1.57));
[UIView animateWithDuration:5 animations:^{
myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0);
}];
たぶん、CGAffineTransformMakeTranslateとCGAffineTransformConcatを使用する必要もあるかもしれませんが、それもよくわかりません。
これについての最悪の部分は次のとおりです。これはiOS7で奇妙に見えるため、iOSバージョンではif/elseを実行する必要があります。これは、iOS8の前または使用時にAppleによって修正されることを願っています。リリース。
これは完全に関連しているわけではありませんが、かなり複雑なアニメーションでCGAffineTransformScale
がiOS7でまったく機能しないことに苦労していました。私の問題は、iOS7がCGAffineTransformScale
とCGAffineTransformRotate
を同時に計算できないことでした。 iOS7では、最後に行ったアニメーション呼び出しだけがアニメーション化されるため、回転のみが発生していました。このバグはiOS8で修正されています。
私の解決策は、iOS7のアニメーションを単純化して、iOS8の凝ったものだけをオンにすることです。
_//Pre-animation setup:
CGFloat radians = (M_PI/180) * (-15); //Get a human-readable number in degrees
self.badgeImage.alpha = 0; //Start the image as invisible
self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 1.5, 1.5); //Start the image as scaled bigger than normal
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //See below. We will not be rotating the image in iOS7
self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, radians); //Rotate the image if iOS8
}
//Animation Pieces:
//Fade in
[UIView animateWithDuration: 0.5
delay:0
options:0
animations:^{
self.badgeImage.alpha = 1.0f; //Return image to opaque
}
completion:NULL];
//Scale with bounce
[UIView animateWithDuration: 1.1
delay:0
usingSpringWithDamping:0.3 //Not as good as Android's bounce interpolator, but I'll take it
initialSpringVelocity:-1.0f //A negative velocity here makes the animation appear more like gravity than spring
options:0
animations:^{
self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 0.67, 0.67); //Return image to its original size. These arguments are relative to its current scale.
}
completion:NULL];
//Rotation
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //This second animation call negates the first one on iOS7, so remove it.
[UIView animateWithDuration: 0.9
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, (radians * -1)); //Rotate the image back to its original orientation if iOS8
}
completion:NULL];
}
_
もちろん、紛らわしい名前のCGAffineTransformMakeScale()
関数を使用すれば、iOS7で複数の効果を組み合わせることができます。たとえば、アニメーション前の設定では、回転とスケールの両方を設定してから、呼び出しCGAffineTransformMakeScale(1,1)
を設定して、画像を元のメトリックにリセットできます(MakeScale
の引数は特定のものであり、相対的-さらに混乱します!)。これは、アニメーションを「バウンス」すると回転もバウンスする上記の例のように、常に好ましいとは限りません。
私は、io8のサイズクラスに関係しているというPbkに同意します。 uiviewcontrollersは、デバイスの向きに応じてuitraitcollectionsを使用してサイズを変更する必要があります。それ以外の場合は、電話を横向きモードにして回転させようとすると、uiviewcontrollerが縦向きモードになります。したがって、正しい手順は、uitraitcollectionsを回転してオーバーライドすることです。