[iOS] transform を使った画像のお手軽回転アニメーション

2011年7月6日水曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

1枚の画像を回転させるアニメーションを実現したい。UIView の transform プロパティを使うと非常に簡単にできることがわかった。


サンプル
初期状態。ここで start を押すと
時計回りに回転が始まり

下を向いた状態で終わる。


実装

用意している画像はこの1枚だけ。


※画像入手元および画像作者
入手元:Arrow, Up icon | Icon Search Engine
作成者: Kyo Tux (ホームページ kyo-tux on deviantART



これを UIImageView.image に設定し、transformプロパティを使って回転させる。こんな感じ。
- (IBAction)start:(id)sender {
    
    self.imageView.transform = CGAffineTransformMakeRotation(0);
    [UIView animateWithDuration:0.2
        animations:^{
            self.imageView.transform =
                CGAffineTransformMakeRotation(2*M_PI*180/360.0-0.000001);                         
        }];
}
最初に transform を CGAffineTransformMakeRotation(0)(角度 0)で初期化し、アニメーションブロックで transform を180度回転させた値を設定している。CGAffineTransformMakeRotation の引数の単位はラジアンなので 2π x 度/360 で角度変換する。最後の -0000001 は右側で回転させる為のおまじない。 これが無いと左側での回転となる。こうやってアニメーションブロックに入れておくと回転中の画像が自動的に作られてスムーズなアニメーションが行える。


その他


当初は NSTimer を使ってコンマ数秒毎に角度を変えて自前にアニメーションを行ってみたが、スムーズなアニメーションを作るには試行錯誤が必要でかなり面倒。
- (void)fire:(NSTimer*)timer
{
    angle_ += 30.0;
    self.imageView.transform = CGAffineTransformMakeRotation(2*M_PI*angle_/360.0);

    if (angle_ >= 180.0) {
        angle_ = 0;
        self.button.enabled = YES;
        [timer invalidate];
    }
}

- (IBAction)start:(id)sender {
    
    [NSTimer scheduledTimerWithTimeInterval:0.05
                                     target:self
                                   selector:@selector(fire:)
                                   userInfo:nil
                                    repeats:YES];
}
上記は 30度単位で回しているがカクカク感が多少ある。UIView のアニメーションを使うとこの当たりの調整が不要で簡単にアニメーションができるので非常に便利。画像も1種類用意しておけば使いまわせるのもいい。


ソースコード


GitHub からどうぞ。
RotateImageSample at 2011-07-06 from xcatsan/iOS-Sample-Code - GitHub


参考情報


CGAffineTransformMakeRotation
transform プロパティの使い方はここが参考になった。

iPhoneアプリ開発、その(64) トランスフォ〜ム|テン*シー*シー
CoreGrapshicsを操作する場合は CGContextRotateCTM などを使う。transformプロパティを使わずに自力で描画しているケースはこちらが参考になる。

Responses

Leave a Response

人気の投稿(過去 30日間)