关键帧动画中的时间系统,模型树和呈现树与基础动画一致,这里主要介绍关键帧动画的用法
CAKeyframeAnimation
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 120, 120); layer.position = CGPointMake(100, 300); layer.cornerRadius = 60; layer.masksToBounds = YES; layer.contents = (id)[UIImage imageNamed:@"5.png"].CGImage; [self.view.layer addSublayer:layer]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CALayer *layer = [self.view.layer.sublayers lastObject]; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //设置关键帧 //与基础动画不同,关键帧动画必须指明动画初始值 NSValue *value1 = [NSValue valueWithCGPoint:layer.position]; NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(50, 300)]; NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(50, 100)]; animation.duration = 2; animation.values = @[value1,value2,value3]; animation.autoreverses = YES; [layer addAnimation:animation forKey:nil]; }
这是关键帧动画的第一种写法,就是设定几个关键节点,然后CoreAnimation自动补齐关键节点中的动画
关键帧的另一种写法是设定动画的path,然后layer可以绕着画好的path移动,这种方式可以方便的实现曲线运动的动画效果
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 120, 120); layer.position = CGPointMake(100, 300); layer.cornerRadius = 60; layer.masksToBounds = YES; layer.contents = (id)[UIImage imageNamed:@"5.png"].CGImage; [self.view.layer addSublayer:layer]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CALayer *layer = [self.view.layer.sublayers lastObject]; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //设置关键帧 //与基础动画不同,关键帧动画必须指明动画初始值 CGPathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, layer.position.x, layer.position.y);//移动到起始点 CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 55, 400);//绘制二次贝塞尔曲线 CGPathRelease(path); animation.path = path; animation.duration = 2; animation.autoreverses = YES; [layer addAnimation:animation forKey:nil]; }
UIView封装关键帧动画
- (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 120, 120)]; imageView.image = [UIImage imageNamed:@"5.png"]; [self.view addSubview:imageView]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UIImageView *image = [self.view.subviews lastObject]; [UIView animateKeyframesWithDuration:5 delay:0 options:UIViewKeyframeAnimationOptionRepeat|UIViewKeyframeAnimationOptionAutoreverse animations:^{ //添加关键帧 //第一个关键帧为开始位置,无需添加 //第二个关键帧:从0秒开始持续50%的时间,也就是5.0*0.5=2.5秒 [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{ image.center = CGPointMake(50, 50); }]; //第三个关键帧,从0.5*5.0秒开始,持续5.0*0.25=1.25秒 [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{ image.center = CGPointMake(150, 50); }]; //第四个关键帧:从0.75*5.0秒开始,持所需5.0*0.25=1.25秒 [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{ image.center = CGPointMake(150, 350); }]; } completion:nil]; }
对于关键帧动画也有一些动画参数设置options,UIViewKeyframeAnimationOptions类型,和上面基本动画参数设置有些差别,关键帧动画设置参数分为两类,可以组合使用:
1.常规动画属性设置(可以同时选择多个进行设置)
UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat:重复运行动画。
UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。
2.动画模式设置(同前面关键帧动画动画模式一一对应,可以从其中选择一个进行设置)
UIViewKeyframeAnimationOptionCalculationModeLinear:连续运算模式。
UIViewKeyframeAnimationOptionCalculationModeDiscrete :离散运算模式。
UIViewKeyframeAnimationOptionCalculationModePaced:均匀执行运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubic:平滑运算模式。
UIViewKeyframeAnimationOptionCalculationModeCubicPaced:平滑均匀运算模式。
注意:前面说过关键帧动画有两种形式,上面演示的是属性值关键帧动画,路径关键帧动画目前UIView还不支持。