IOS 动画

动画 Animation

CALayer是动画产生的地方,当将动画添加到Layer层的时候,不能直接修改layer的属性

  • CoreAnimation 有两个Layer层次结构 - 模型层树(model layer tree)和表示层树(presentation layer tree)
- (instancetype)presentationLayer; - 表示层
- (instancetype)modelLayer; - 模型层
CAAnimation常用的有:
  • CABasicAnimation

CABasicAnimation的常用属性:

  • duration 动画的持续时间
  • beginTime 指定动画开始的时间,从开始延迟几秒的话,设置为CACurrentMediaTime() + 秒数的方式
  • repeatCount 动画的持续次数
  • repeatDuration 设置动画的时间,在该时间内动画一直执行,不计次数
  • autoreverses 动画结束时是否执行逆动画
  • fillMode 动画在开始和结束时的动画,默认值是KCAFillModeRemoved
    • kCAFillModeForwards 动画开始之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值为YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO
    • kCAFillModeBackwards 将会立即执行动画的第一帧,无论是否设置beginTime属性
    • kCAFillModeBoth kCAFillModeForwards和kCAFillModeBackwards的组合状态
    • kCAFillModeRemoved 动画将在设置的beginTime开始执行(若有设置beginTime属性,则动画立刻执行),而动画执行完成后将会将layer的状态恢复原状
  • timingFunction 设置动画的时间变化
  • fromValue 所要改变属性的起始值
  • toValue 所要改变属性的结束时的值
  • byValue 所要改变属性相同起始值的改变量
    • 注:若将removedOnCompletion设置为false状态,则可能会引起循环引用的问题
    • 原因:由于CAAnimation的delegate使用的Strong类型(强引用类型)
一般创建动画的时候,会使用到KeyPath的属性

备注:KeyPath的值

  • positon - 移动位置(CGPoint)
  • opacitu - 透明度(0-1)
  • bounds - 变大与位置(CGRect)
  • bounds.size - 由小变大(CGSize)
  • backgroundColor - 背景颜色(CGColor)
  • cornerRadius - 渐变圆角(任意数值)
  • borderWidth - 改变边框border的大小(图形周围边框,border默认为黑色) (任意数值)
  • contens - 改变layer内容(图片) 若想要达到改变内容的动画效果,则要先在运行之前定义好layer的contents (CGImage)
  • transform.scale - 缩放,放大(0.0-1.0)
  • transform.rotation.x - 旋转动画(翻转,沿着X轴)(M_PI * n)
  • transform.rotation.y - 旋转动画(沿着Y轴)(M_PI * n)
  • transform.rotation.z - 旋转动画(沿着Z轴)(M_PI * n)
  • transform.transiation.x - 横向移动(沿着X轴)(任意数值)
  • transform.transiation.y - 纵向移动(沿着Y轴)(任意数值)

旋转动画

#pragma mark - 旋转动画 -
-(void)setRotateView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 70, 70)];
    animationView.backgroundColor = [UIColor orangeColor];
    
    //将AnimationView添加到self.view上
    [self.view addSubview:animationView];
    //2.创建动画图层
    /**
     3.设置keyPath的常用属性:
     transform.rotation.x  围绕x轴旋转
     transform.rotation.y  围绕y轴旋转
     transform.rotation.z  围绕z轴旋转
     */
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
    
    //4.设置beginTime指定动画开始的时间,从开始延迟几秒的话,设置为CACurrentMediaTime() + 秒数的方式
    basic.beginTime = 0.0;
    
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(2*M_PI, 0)];
    
    //6.设置duration动画的持续时间
    basic.duration = 1.5;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    
    /**
     timingFunction   设置动画的时间变化
     kCAMediaTimingFunctionLinear   在整个动画时间内动画都是以相同速度来改变 - 匀速运动
     kCAMediaTimingFunctionEaseIn   动画开始慢,之后加速                 - 加速运动
     kCAMediaTimingFunctionEaseOut  动画开始快,之后减速                 - 减速运动
     kCAMediaTimingFunctionEaseInEaseOut  动画在开始和结束都慢,中间时间段内速度较快
     kCAMediaTimingFunctionDefault  默认动画
     */
    //[basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    
    //8.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
 
}

移动动画

#pragma mark - 移动动画 -
-(void)SetMoveAnimationView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 120, 70, 70)];
    animationView.backgroundColor = [UIColor orangeColor];
    
    //将AnimationView添加到self.view上
    [self.view addSubview:animationView];
    //2.创建动画图层
    /**3.position    设置内容(eg:UIImage)*/
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"position"];
    
    //4.fromValue所要改变属性的起始值
    basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(40, 240)];
    
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 240)];
    
    //6.设置duration动画的持续时间
    basic.duration = 2;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

背景颜色变化动画

#pragma mark - 背景颜色变化动画 -
-(void)SetBackgroundColorChangeAnimationView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(100, 50, 70, 70)];
    animationView.backgroundColor = [UIColor orangeColor];
    
    //将AnimationView添加到self.view上
    [self.view addSubview:animationView];
    //2.创建动画图层
    //backgroundColor       设置背景颜色的变化
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    
    //4.fromValue所要改变属性的起始值
    basic.fromValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);
    
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = (__bridge id _Nullable)([UIColor lightGrayColor].CGColor);
    
    //6.设置duration动画的持续时间
    basic.duration = 2;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
    
}

内容改变动画

#pragma mark - 内容改变动画 -
-(void)SetContantChangeAnimationView
{
    //1.创建一个View图层
    UIImageView *animationView = [[UIImageView alloc]initWithFrame:CGRectMake(200, 50, 70, 70)];
    animationView.image = [UIImage imageNamed:@"from"];
    
    [self.view addSubview:animationView];
    //2.创建动画图层 contents
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"contents"];
    
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = (__bridge id _Nullable)([UIImage imageNamed:@"to"].CGImage);
    
    //6.设置duration动画的持续时间
    basic.duration = 1.5;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

转换圆角动画

#pragma mark - 圆角变化动画 -
-(void)SetRadiusView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 310, 70, 70)];
    animationView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:animationView];
    animationView.layer.masksToBounds = YES;
    //2.创建动画图层 contents
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
    
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(35, 0)];
    
    //6.设置duration动画的持续时间
    basic.duration = 2;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

按比例缩放动画

#pragma mark - 按比例缩放动画 -
-(void)SetZoomAnimationView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(10, 400, 70, 70)];
    animationView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:animationView];
    //2.创建动画图层 contents
    /**
     transform.scale 按比例缩放 - 0.8
     transform.scale.x  缩放宽的比例
     transform.scale.y  缩放高的比例
     */
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    basic.fromValue = [NSValue valueWithCGPoint:CGPointMake(0.3, 0)];
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(1.3, 0)];
    
    //6.设置duration动画的持续时间
    basic.duration = 2;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

按指定大小进行缩放动画

#pragma mark - 指定大小缩放 -
-(void)SetAssginZoomView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(120, 400, 70, 70)];
    animationView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:animationView];
    //2.创建动画图层 contents
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"bounds"];
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGRect:CGRectMake(800, 500, 90, 30)];
    
    //6.设置duration动画的持续时间
    basic.duration = 2;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

设置渐变动画(透明)

#pragma mark - 透明动画 -
-(void)SetAlphaAnimationView
{
    //1.创建一个View图层
    UIView *animationView = [[UIView alloc]initWithFrame:CGRectMake(300, 50, 70, 70)];
    animationView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:animationView];
    //2.创建动画图层 contents
    CABasicAnimation * basic = [CABasicAnimation animationWithKeyPath:@"opacity"];
    basic.fromValue= [NSValue valueWithCGPoint:CGPointMake(0.3, 0)];
    //5.设置toValue所要改变属性的结束时的值
    basic.toValue = [NSValue valueWithCGPoint:CGPointMake(1, 0)];
    
    //6.设置duration动画的持续时间
    basic.duration = 0.6;
    
    //7.设置repeatCount动画的持续次数
    basic.repeatCount = INFINITY;
    //8.autoreverses动画结束时是否执行逆动画
    basic.autoreverses = YES;
    //10.将动画添加到图层
    [animationView.layer addAnimation:basic forKey:@"basic"];
}

  • CAKeyframeAnimation(关键帧动画)

常用属性有:

  • values 当path=nil的时候才起作用
  • keyTimes 一个包含若干NSNumber(浮点型值在0.0~1.0之间)对象值得数组,用来区分动画的分割时机
  • calculationMode 计算模式 主要针对的是每一帧的内容来为一个坐标点的情况,也就是对anchorPoint和Position进行的动画
    • kCAAnimationLinear 默认值 自定义控制动画的时间,可以设置keyTimes,表示当关键帧为坐标点的时候,关键帧之间之间直线相连进行插针计算 线性的
    • kCAAnimationDiscrete 离散的 不进行插值计算 所有关键帧之间逐个儿进行显示
    • kCAAnimationPaced 节奏动画,自动计算动画的运动时间,使得动画匀速运行 keyTimes和timingFunctions无效
    • kCAAnimationCubic 对关键帧为坐标点的关键帧进行圆滑曲线相连后进行插值计算 若为曲线形状,可通过tensionValues,continuityValues,biasValues来进行调整自定义,其主要目的是使得运行轨迹变得圆滑,而曲线动画则要设置timingFunctions
    • kCAAnimationCubicPaced 在系统时间内运行的距离相同,keyTimes和timingFunctions无效
  • rotationMode 旋转样式
    • kCAAnimationRotateAuto 根据路径自动旋转
    • kCAAnimationRotateAutoReverse 根据路径自动翻转
创建一个例子来实现一下
#pragma mark - CAKeyframeAnimation 核心动画里面的帧动画 -
-(void)setCAKeyframeAnimationView
{
    //1.创建View
    UIView * keyFrameAnimation = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
    keyFrameAnimation.center = CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.height/2.0-50);
    //2.创建贝塞尔曲线
    UIBezierPath * bezierPath = [UIBezierPath bezierPathWithOvalInRect:keyFrameAnimation.frame];
    //3.再创建一个存放动画的View
    UIView * animationView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 70, 80)];
    animationView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:animationView];
    //2.创建帧动画
    CAKeyframeAnimation * keyframe = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyframe.duration = 5;
    keyframe.path = bezierPath.CGPath;
    /**
     calculationMode的属性:
     kCAAnimationLinear  默认值 自定义控制动画的时间,可以设置keyTimes,表示当关键帧为坐标点的时候,关键帧之间之间直线相连进行插针计算  线性的
     kCAAnimationDiscrete 离散的 不进行插值计算 所有关键帧之间逐个儿进行显示
     kCAAnimationPaced  节奏动画,自动计算动画的运动时间,使得动画匀速运行 keyTimes和timingFunctions无效
     kCAAnimationCubic  对关键帧为坐标点的关键帧进行圆滑曲线相连后进行插值计算 若为曲线形状,可通过tensionValues,continuityValues,biasValues来进行调整自定义,其主要目的是使得运行轨迹变得圆滑,而曲线动画则要设置timingFunctions
     kCAAnimationCubicPaced  在系统时间内运行的距离相同,keyTimes和timingFunctions无效
     */
    //calculationMode   计算模式 主要针对的是每一帧的内容来为一个坐标点的情况,也就是对anchorPoint和Position进行的动画
    keyframe.calculationMode = kCAAnimationPaced;
    keyframe.repeatCount = INFINITY;
    //设置旋转样式
    /**
     kCAAnimationRotateAuto  根据路径自动旋转
     kCAAnimationRotateAutoReverse  根据路径自动翻转
     */
    keyframe.rotationMode = kCAAnimationRotateAutoReverse;
    [animationView.layer addAnimation:keyframe forKey:@"keyframe"];
    
    //创建CAShapeLayer
    CAShapeLayer * shape = [[CAShapeLayer alloc]init];
    shape.strokeColor = [UIColor lightGrayColor].CGColor;
    shape.fillColor = [UIColor clearColor].CGColor;
    shape.lineWidth = 0.5;
    shape.lineJoin = kCALineJoinRound;
    shape.lineCap = kCALineCapRound;
    shape.path = bezierPath.CGPath;
    [self.view.layer addSublayer:shape];
}

  • CATransition(转场动画)

CATransition的常用属性有:

  • type - 转场动画的类型
    • kCATransitionFade 淡出效果 (支持方向)
    • kCATransitionMoveIn 将新视图移动到旧视图上 (支持方向)
    • kCATransitionPush 用新视图来推出旧视图 (支持方向)
    • kCATransitionReveal 将旧视图移开后再显示新视图 (支持方向)
  • subtype - 转场动画将要去往的方向
    • kCATransitionFromRight 从右侧转场
    • kCATransitionFromLeft 从左侧转场
    • kCATransitionFromTop 从顶部转场
    • kCATransitionFromBottom 从底部转场
  • TimingFunction - 时间函数
  • repeatCount - 重复显示次数
创建一个例子来实现上述属性:
#pragma mark - CATransition 主要用于转场动画从一个场景以动画的形式来过渡到另一个场景 -
-(void)setCATransitionView
{
    //1、创建显示效果名称的label
    self.textLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
    self.textLabel.center = CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.width/2.0);
    self.textLabel.backgroundColor = [UIColor colorWithRed:88/255.0 green:161/255.0 blue:86/255.0 alpha:1];
    self.textLabel.textColor = [UIColor whiteColor];
    self.textLabel.font = [UIFont systemFontOfSize:16];
    self.textLabel.numberOfLines = 0;
    self.textLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.textLabel];
    
    //创建按钮
    self.clickButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 180, 40)];
    self.clickButton.center = CGPointMake(self.view.frame.size.width/2.0f, self.view.frame.size.height-240);
    self.clickButton.backgroundColor = [UIColor blackColor];
    [self.clickButton setTitle:@"AnimationChange" forState:UIControlStateNormal];
    self.clickButton.titleLabel.textAlignment = NSTextAlignmentCenter;
    [self.clickButton addTarget:self action:@selector(ClickButton) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.clickButton];
}
//MARK:点击按钮,开始改变转场动画效果
-(void)ClickButton
{
    //创建转场动画图层
    CATransition * transition = [CATransition new];
    //设置代理事件
    transition.delegate = self;
    //设置时间
    transition.duration = 1.0;
    //设置时间函数
    /**
     kCAMediaTimingFunctionLinear
     kCAMediaTimingFunctionEaseIn
     kCAMediaTimingFunctionEaseOut
     kCAMediaTimingFunctionEaseInEaseOut
     kCAMediaTimingFunctionDefault 默认
     */
    [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    
    //设置转场动画类型 默认从第一个开始
    [transition setType:self.animationArray[_index]];
    
    //设置转场动画的方向
    /**
     kCATransitionFromRight  从右侧转场
     kCATransitionFromLeft   从左侧转场
     kCATransitionFromTop    从顶部转场
     kCATransitionFromBottom 从底部转场
     */
    transition.subtype = kCATransitionFromLeft;
    //设置重复次数
    transition.repeatCount = 1;
    //设置键值对
    [transition setValue:@"transitionAnim" forKey:@"anim"];
    //添加到视图
    [self.textLabel.layer addAnimation:transition forKey:@"transition"];
    self.textLabel.text = [NSString stringWithFormat:@"This Animation was %@",self.animationArray[_index]];
}
#pragma mark - 实现CAAnimationDelegate方法 -
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    _index = (_index
  • CASpringAnimation(弹簧动画)

CASpringAnimation的常用属性有:

  • mass 质量,影响图层运动时的弹簧惯性,质量越大,弹簧的拉伸和压缩的幅度越大,动画的速度变慢,并且波动幅度变大
  • stiffness 刚度系数 = 劲度系数/弹性系数 当刚度系数越大的时候,形变所产生的力就越大,运动就越快
  • damping 阻尼系数 阻止弹簧伸缩的系数,阻尼系数越大,停止越快
  • initialVelocity 初始速率,动画的初始速度大小速率为正数时,速度方向与运动方向一致,当速率为负数的时候,速度方向和运动方向相反
  • settingDuration 结算时间,返回弹簧动画到停止时的估算时间,根据当前的动画参数估算通常动画的时间使用结算时间比较准确
创建一个例子来实现上述属性
#pragma mark - CASpringAnimation 弹簧动画-
-(void)setCASpringAnimationView
{
    //创建label
    self.textLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 200, 50, 30)];
    self.textLabel.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.textLabel];
    
    //创建弹簧动画
    CASpringAnimation * spring = [CASpringAnimation animationWithKeyPath:@"position.x"];
    spring.damping = 5;
    spring.stiffness = 100;
    spring.mass = 1;
    spring.initialVelocity = 0;
    spring.fromValue = [NSValue valueWithCGPoint:CGPointMake(self.textLabel.layer.position.x, 0)];
    spring.toValue = [NSValue valueWithCGPoint:CGPointMake(self.textLabel.layer.position.x+100, 0)];
    spring.autoreverses = YES;
    spring.repeatCount = INFINITY;
    [self.textLabel.layer addAnimation:spring forKey:spring.keyPath];
}

备注:

  • CABasicAnimation(基础动画)和CAKeyframeAnimation(帧动画)的区别&联系
  • CABasicAnimation可以看做是最多只有两个关键帧的CAKeyframeAnimation

你可能感兴趣的:(IOS 动画)