#アニメーションが動かない
##animateWithDuration
Objective-Cでアニメーションを実装する場合、次のようなコードを書く場合があります。(有名な「逆引きObjective-C」のものをつかっています。)
自分の環境の場合、このコードは動くのですが、拡大・縮小だけでなく移動を入れようとするととたんに動かなくなりました。
- (void)viewDidLoad
{
[super viewDidLoad];
// 画像を表示する
UIImage *image = [UIImage imageNamed:@"image01.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
imageView.center = CGPointMake(160, 240);
[self.view addSubview:imageView];
// アニメーション
[UIView animateWithDuration:2.5f // アニメーション速度2.5秒
delay:1.0f // 1秒後にアニメーション
options:UIViewAnimationOptionCurveEaseIn
animations:^{
// 画像を2倍に拡大
imageView.transform = CGAffineTransformMakeScale(2.0, 2.0);
} completion:^(BOOL finished) {
// アニメーション終了時
NSLog(@"アニメーション終了");
}];
}
コードは完璧なのに・・・。なぜでしょうか?
#原因
AutoLayoutを使用した場合、viewDidLoad,viewWillAppearではframeが決定していないようです(参考: [iOS6] AutoLayoutを使用すると、viewWillAppear: でframeが決定しないので注意)そのため、このタイミングでanimationを開始した場合挙動が環境によっては不安定になります。(Xcodeのバージョンによっても変わる模様)
以下のライフサイクルが分かっている人にとってはある当然のことかもしれません。(viewDidLoadのタイミングでは画面はまだ表示されていないから)
イベント | iOS |
---|---|
クラスが生成されたとき | init |
画面がロードされる前 | loadView |
画面がロードされた時 | viewDidLoad |
UIの配置が行われる前 | viewWillLayoutSubviews |
UIの配置が行われた後 | viewDidLayoutSubviews |
画面が表示される直前 | viewWillAppear |
画面が表示された直後 | viewDidAppear |
#解決策
###解決策1:viewDidAppear後にアニメーションを開始する
以下のように書きます
-(void)viewDidAppear:(BOOL)animated{
// 画像を表示する
UIImage *image = [UIImage imageNamed:@"image01.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
imageView.center = CGPointMake(160, 240);
[self.view addSubview:imageView];
// アニメーション
[UIView animateWithDuration:2.5f // アニメーション速度2.5秒
delay:1.0f // 1秒後にアニメーション
options:UIViewAnimationOptionCurveEaseIn
animations:^{
// 画像を2倍に拡大
imageView.transform = CGAffineTransformMakeScale(2.0, 2.0);
} completion:^(BOOL finished) {
// アニメーション終了時
NSLog(@"アニメーション終了");
}];
}
##解決策2:autolayoutのチェックを外す
autolayoutが悪いならautolayoutしなければよい、ということでautolayoutのチェックを外してやっても解決します