UIViewで手軽にアニメーションを実行する方法
UIViewにはアニメーション関連メソッドが用意されているので、お手軽にアニメーションを実行することができます。ボタン、ラベル、画像などは全てUIViewを継承しているので基本的に全て同じ方法で実行可能です。
まずはUIViewの初期化メソッドでUIButtonを生成してViewに追加しておきます。このボタンが押されると@selector()で指定してあるメソッドが呼ばれるので、そこでアニメーションを実行します。
- (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor whiteColor]; // button UIButton *btn= [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btn setFrame:CGRectMake(0.0, 0.0, 100.0, 50.0)]; [btn setCenter:CGPointMake(160.0, 200.0)]; [btn setTitle:@"TEST" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(startAnimation:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } return self; }
UIViewのアニメーションの設定はbeginAnimationsで始まり、commitAnimationsで終わります。基本的には下記コードをそのまま記述し、//TODO: と記載している箇所でアニメーション終了後のUI部品の状態を指定しておくだけでOKです。あとはフレームワークがその間の座標を補完してアニメーションにしてくれます。
-(void)startAnimation:(id)sender{ UIButton *btn = (UIButton *)sender; //アニメーションの対象となるコンテキスト CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; //アニメーションを実行する時間 [UIView setAnimationDuration:0.5]; //アニメーションイベントを受け取るview [UIView setAnimationDelegate:self]; //アニメーション終了後に実行される [UIView setAnimationDidStopSelector:@selector(endAnimation)]; //TODO: // アニメーション開始 [UIView commitAnimations]; }
TODOの箇所には色々かけますが、例えば座標変更や、透明度の変更は下記のように指定します。
//中心座標を変更する [btn setCenter:CGPointMake(0,0)]; //座標を変更する1 CGRect rect = [btn frame]; rect.origin.y = 200; [btn setFrame:rect]; //座標を変更する2 [btn setFrame:CGRectMake(0,100,100,50)]; //透明にする [btn setAlpha:0.0];
回転させる場合にはおなじみのアフィン変換も、メソッドが用意されているので手軽に実行することができます。
//90度回転 CGAffineTransform rotate = CGAffineTransformMakeRotation(90.0f * (M_PI / 180.0f)); [btn setTransform:rotate]; //縦横2倍に拡大 CGAffineTransform scale = CGAffineTransformMakeScale(2.0, 2.0); [btn setTransform:scale]; //XY方向に100px平行移動 CGAffineTransform translate = CGAffineTransformMakeTranslation(100.0, 100.0); [btn setTransform:translate];
上記はそれぞれ下記のようにも記述できます。
//平行移動 (下記行列のx, yを指定する) // 1 0 0 // 0 1 0 // x y 1 CGAffineTransform translate2 = CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 100.0, 100.0); [btn setTransform:translate2]; //スケール (下記行列のx, yを指定する) // x 0 0 // 0 y 0 // 0 0 1 CGAffineTransform scale2 = CGAffineTransformMake(2.0, 0.0, 0.0, 2.0, 0.0, 0.0); [btn setTransform:scale2]; //回転 (下記行列のsin, cosを指定する) // cosA sinA 0 //-sinA cosA 0 // 0 0 1 float rd = 90.0f * (M_PI / 180.0f); CGAffineTransform rotate2 = CGAffineTransformMake(cos(rd), sin(rd), -sin(rd), cos(rd), 0.0, 0.0); [btn setTransform:rotate2];
複数の変換を同時に指定したい場合は自分で演算してCGAffineTransformMakeで一括指定してもよいですが、CGAffineTransformConcatというメソッドを利用すれば楽そうです。
//すべての変換を統合
CGAffineTransform concat = CGAffineTransformConcat(CGAffineTransformConcat(rotate, scale), translate);
[btn setTransform:concat];
アニメーションが終了した後には、setAnimationDidStopSelectorで指定したメソッドが実行されます。2段階でアニメーションを実行したい場合などはこの中で再度別のアニメーションを定義して実行するとよいです。次のコードを実行すると、rollオブジェクトが2回転して止まります。
CGFloat affinea = 0.0f; -(void) startAnimation{ CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; [UIView setAnimationDuration:0.02f]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(endAnimation)]; roll.transform = CGAffineTransformMakeRotation(affinea * (M_PI / 180.0f)); [UIView commitAnimations]; } -(void)endAnimation{ affinea += 10.0f; if(affinea < 360.0f*2){ [self startAnimation]; }else{ affinea = 0.0f; roll.transform = CGAffineTransformMakeRotation(0); } }
これだけお手軽に実行できると作ってて楽しいですね。