IOS动画核心 之 KeyFrameAnimation简介
直接上代码吧
1,在viewdidload方法里面定义两个按钮:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
// Do any additional setup after loading the view, typically from a nib.
UIButton *lineBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
lineBtn.frame = CGRectMake(self.view.bounds.size.width -100, self.view.bounds.size.height - 54, 60, 40);
[lineBtn setTitle:@"Line" forState:UIControlStateNormal];
[lineBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[lineBtn addTarget:self action:@selector(lineAnimation:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:lineBtn];
UIButton *circleBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
circleBtn.frame = CGRectMake(self.view.bounds.size.width -100, self.view.bounds.size.height - 54*2, 60, 40);
[circleBtn setTitle:@"Circle" forState:UIControlStateNormal];
[circleBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[circleBtn addTarget:self action:@selector(circleAnimation:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:circleBtn];
}
2,直线上下回荡动画
//直线动画
- (void)lineAnimation:(id)sender
{
NSLog(@"you have clicked the button !");
btnIsSelect = !btnIsSelect;
UIImageView *animationView = (UIImageView *)[self.view viewWithTag:1000];
if (animationView)
{
[animationView removeFromSuperview];
}
animationView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"video_add.png"]];
animationView.frame = CGRectMake(80, self.view.bounds.size.height, 54, 54);
animationView.tag = 1000;
[self.view addSubview:animationView];
if (btnIsSelect)
{
CAKeyframeAnimation *keyCallAnimation = [CAKeyframeAnimation animation]; //关键帧动画并不是改变frame,控件的实际坐标位置是没有发生变化的。
keyCallAnimation.keyPath = @"position"; // 需要做动画的属性
keyCallAnimation.delegate = self; //设置代理
keyCallAnimation.removedOnCompletion = NO; //动画完成后是否移除:NO 不移除 YES 移除(默认)
/*
kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态
kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.
*/
keyCallAnimation.fillMode = kCAFillModeForwards; //让动画的layer保持结束状态 前提 removedOnCompletion = NO;
keyCallAnimation.duration = 0.3f; //持续时间
keyCallAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
//设置关键路径 ,关键路径可以是一个圆
NSValue *callPath1 = [NSValue valueWithCGPoint:animationView.center];
NSValue *callPath2 = [NSValue valueWithCGPoint:CGPointMake(animationView.center.x, self.view.center.y)];
NSValue *callPath3 = [NSValue valueWithCGPoint:CGPointMake(animationView.center.x, self.view.center.y + 15)];
NSValue *callPath4 = [NSValue valueWithCGPoint:CGPointMake(animationView.center.x, self.view.center.y)];
keyCallAnimation.values = @[callPath1,callPath2, callPath3, callPath4];
//设置关键路径的时间点 范围【0~1】
NSNumber *callTime1 = [NSNumber numberWithFloat:0.0f];
NSNumber *callTime2 = [NSNumber numberWithFloat:0.5f];
NSNumber *callTime3 = [NSNumber numberWithFloat:0.75f];
NSNumber *callTime4 = [NSNumber numberWithFloat:1.0f];
keyCallAnimation.keyTimes = @[callTime1,callTime2,callTime3,callTime4];
[animationView.layer addAnimation:keyCallAnimation forKey:nil];
}
else
{
if (animationView)
{
animationView.center = CGPointMake(animationView.center.x, self.view.center.y);
CAKeyframeAnimation *keyCallAnimation = [CAKeyframeAnimation animation]; //关键帧动画并不是改变frame,控件的实际坐标位置是没有发生变化的。
keyCallAnimation.keyPath = @"position"; // 需要做动画的属性
keyCallAnimation.delegate = self; //设置代理
keyCallAnimation.removedOnCompletion = NO; //动画完成后是否移除:NO 不移除 YES 移除(默认)
keyCallAnimation.fillMode = kCAFillModeForwards; //让动画的layer保持结束状态 前提 removedOnCompletion = NO;
keyCallAnimation.duration = 0.3f; //持续时间
keyCallAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
NSValue *callPath1 = [NSValue valueWithCGPoint:animationView.center];
NSValue *callPath2 = [NSValue valueWithCGPoint:CGPointMake(animationView.center.x, -animationView.frame.size.height)];
keyCallAnimation.values = @[callPath1,callPath2];
[animationView.layer addAnimation:keyCallAnimation forKey:nil];
}
}
[animationView release];
}
3,按圆运动动画,效果不是很好,需要优化,大概就是这个样子
- (void)circleAnimation:(id)sender
{
UIImageView *earchImgView = (UIImageView *)[self.view viewWithTag:1001];
UIImageView *circleImgView = (UIImageView *)[self.view viewWithTag:1002];
if (earchImgView)
{
[earchImgView removeFromSuperview];
}
if (circleImgView)
{
[circleImgView removeFromSuperview];
}
earchImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"earch.jpg"]];
earchImgView.tag = 1001;
earchImgView.frame = CGRectMake(0, 0, 50, 50);
[self.view addSubview:earchImgView];
UIGraphicsBeginImageContext(CGSizeMake(320,460));
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextBeginPath(ctx);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextAddArc(ctx, self.view.center.x, self.view.center.y, 100, 0, 2*M_PI, 1);
CGContextDrawPath(ctx, kCGPathStroke);
UIImage *circleImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
circleImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height)];
circleImgView.center = CGPointMake(self.view.center.x, self.view.center.y - 50);
circleImgView.tag = 1002;
circleImgView.image = circleImg;
[self.view addSubview:circleImgView];
[circleImgView release];
CAKeyframeAnimation *keyCallAnimation = [CAKeyframeAnimation animation]; //关键帧动画并不是改变frame,控件的实际坐标位置是没有发生变化的。
keyCallAnimation.keyPath = @"position"; // 需要做动画的属性
keyCallAnimation.delegate = self; //设置代理
keyCallAnimation.removedOnCompletion = NO; //动画完成后是否移除:NO 不移除 YES 移除(默认)
keyCallAnimation.fillMode = kCAFillModeForwards; //让动画的layer保持结束状态 前提 removedOnCompletion = NO;
keyCallAnimation.duration = 1.0f; //持续时间
keyCallAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
keyCallAnimation.repeatCount = 1000;
CGMutablePathRef curvedPath = CGPathCreateMutable(); //设置运转动画的路径
// 1, 2,NULL 3,4 :圆心 5,6 :角度,7:顺时针,逆时针
CGPathAddArc(curvedPath, NULL, self.view.center.x, self.view.center.y, 120.0f, 0, 2*M_PI, 0);
keyCallAnimation.path = curvedPath;
CGPathRelease(curvedPath);
[earchImgView.layer addAnimation:keyCallAnimation forKey:nil];
[earchImgView release];
}
代码分享:链接: http://pan.baidu.com/s/1gdEKFmz 密码: j2dc
链接: http://pan.baidu.com/s/1qWJSbBu 密码: p8bk