Posted at

iOS8でCGAffineTransformの挙動がおかしな件

More than 3 years have passed since last update.


はじめに

自作のアプリにで、ViewのアニメーションをCGAffineTransformを使用している箇所があるのですが、iOS8からアニメーションが効かなくなったので、調査してみました。


該当箇所

//self.touchLayerViewはView独自のUIViewプロパティ

[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.touchLayerView.transform = CGAffineTransformMakeScale(0.0, 0.0);
} completion:^(BOOL finished) {
}];

元々、UIViewの+ animateWithDuration:delay:options:animations:completion:を使用して、

特定ViewのtransformのZoomScaleを0にする実装をしていました。

iOS7以前ではこのコードで動作していましたが、iOS8から動作しなくなりました。

(Auto Layout,Interface Builderなどは使用せず、Viewを直接実装しています)

いろいろと調べた結果、これといった情報は得られませんでした。

関係があるかどうかは定かではありませんが、iOS8のバグであると指摘する人もいました。

直接的な原因としては、CGAffineTransformMakeScaleのサイズに0を指定する事でアニメーションが上手く動作しなくなってしまう様でしたので、暫定的ですが下記の対応で期待する動作は得られました。

//self.touchLayerViewはView独自のUIViewプロパティ

[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.touchLayerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
} completion:^(BOOL finished) {
self.touchLayerView.transform = CGAffineTransformMakeScale(0.0, 0.0);
}];

限りなく0に近い値を入れておき、最終的に0にするという方法で逃げています。


おわりに

stack overflowでもあるように、CALayerのアニメーションを使ってやった方が実装的にはあるべき姿な気がします。

UIViewのアニメーションは便利なんですが、こういうときに予期しない動作をしたり、CALayerで作り直そうとしたときに使い回せなかったりするので、実装時に今後の拡張性含めて検討する必要がありそうです。


参考資料