ios开发中动画那点事

一:UIKit动画

在介绍CoreAnimation动画前先简单介绍一下UIKit动画,大部分简单的动画都可以使用UIKit动画实现,如果想实现更复杂的效果,则需要使用Core Animation了,Core Animation中包含了可以实现更为复杂的基础动画和关键帧动画等等。UIKit动画有两种写法,它不仅可以针对视图还可以针对其它控件。

1:第一种写法是利用属性,结合beginAnimations、commitAnimations

-(void)animationOfUIKit
{
    UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
    redView.backgroundColor=[UIColor redColor];

    [self.view addSubview:redView];
    //开始动画
    [UIView beginAnimations:@"test" context:nil];
    //动画时长
    [UIView setAnimationDuration:1];


    /* *要进行动画设置的地方 */
    redView.backgroundColor=[UIColor blueColor];
    redView.frame=CGRectMake(50, 50, 200, 200);
    redView.alpha=0.5;

    //动画结束
    [UIView commitAnimations];
}

2:第二种写法也是比较常见的,UIKit已经对它进行了封装,方便我门使用

-(void)animationOfBlock
{
    //初始化一个View,用来显示动画
    UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(10, 80, 100, 100)];
    redView.backgroundColor=[UIColor redColor];

    [self.view addSubview:redView];

    [UIView animateWithDuration:2.0 //时长
                          delay:0 //延迟时间
                        options:UIViewAnimationOptionTransitionFlipFromLeft//动画效果
                     animations:^{
                         //动画设置区域
                         redView.backgroundColor=[UIColor blueColor];
                         redView.frame=CGRectMake(50, 100, 200, 200);
                         redView.alpha=0.5;

                     } completion:^(BOOL finish){
                         //动画结束时调用
                         NSLog(@"结束动画");
                     }];
}

注意:关于动画效果的枚举如下:

  • 常规动画属性设置(可以同时选择多个进行设置)

UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat:重复运行动画。
UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。
UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意仅仅适用于转场动画)。
UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)
UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。

  • 动画速度控制(可从其中选择一个设置)

UIViewAnimationOptionCurveEaseInOut:动画先缓慢,然后逐渐加速。

UIViewAnimationOptionCurveEaseIn :动画逐渐变慢。

UIViewAnimationOptionCurveEaseOut:动画逐渐加速。

UIViewAnimationOptionCurveLinear :动画匀速执行,默认值。

  • 转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置)

UIViewAnimationOptionTransitionNone:没有转场动画效果。

UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。

UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。

UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。

UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。

UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。

UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。

UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果。

二:CoreAnimation介绍

1:Core Animation是直接作用在CALayer上的(并非UIView上)非常强大的跨Mac OS X和iOS平台的动画处理API,Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。CAAnimation分为这4种,他们分别是:

  • CABasicAnimation---基本动画
  • CAKeyframeAnimation---关键帧动画
  • CAAnimationGroup---动画组
  • CATransition---转场动画

CABasicAnimation(基本动画)

属性说明:

keyPath :要改变的属性名称(传字符串)

fromValue:keyPath相应属性的初始值

toValue:keyPath相应属性的结束值

动画过程说明:

随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue

keyPath内容是CALayer的动画Animatable属性

animationWithKeyPath的值:

transform.rotation.x 围绕x轴翻转 参数:角度 angle2Radian(4)

transform.rotation.y 围绕y轴翻转 参数:同上

transform.rotation.z 围绕z轴翻转 参数:同上

transform.rotation 默认围绕z轴

transform.scale.x x方向缩放 参数:缩放比例 1.5

transform.scale.y y方向缩放 参数:同上

transform.scale.z z方向缩放 参数:同上

transform.scale 所有方向缩放 参数:同上

transform.translation.x x方向移动 参数:x轴上的坐标 100

transform.translation.y x方向移动 参数:y轴上的坐标

transform.translation.z x方向移动 参数:z轴上的坐标

transform.translation 移动 参数:移动到的点 (100,100)

opacity 透明度 参数:透明度 0.5

backgroundColor 背景颜色 参数:颜色 (id)[[UIColor redColor] CGColor]

cornerRadius 圆角 参数:圆角半径 5

borderWidth 边框宽度 参数:边框宽度 5

bounds 大小 参数:CGRect

contents 内容 参数:CGImage

contentsRect 可视内容 参数:CGRect 值是0~1之间的小数

hidden 是否隐藏

实例:

CALayer *myLayer = [CALayer layer];
    myLayer.backgroundColor = [UIColor purpleColor].CGColor;
    myLayer.frame = CGRectMake(50, 100, 120, 120);
    myLayer.cornerRadius = 10;
    [self.view.layer addSublayer:myLayer];

    //移动
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.fromValue = [NSValue valueWithCGPoint:myLayer.position];
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(myLayer.position.x+100, 100)];

    //以X轴旋转
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
    rotationAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    rotationAnimation.toValue = [NSNumber numberWithFloat:6.0*M_PI];

    //放大缩小
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
    scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    scaleAnimation.toValue = [NSNumber numberWithFloat:2];

 //组合动画
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.autoreverses = YES; //完成动画后同样反向也执行动画
    group.duration = 2.0; //动画时间
    group.animations = [NSArray arrayWithObjects:animation,rotationAnimation,scaleAnimation, nil];
    group.repeatCount = 3;

    /** * PS:动画结束以后,他会返回到自己原来的frame,如果想保持动画结束时的状态 * 添加下面属性,并且此时要保证autoreverses属性为NO,另外组合动画的属性设 * 置同样也适用于单个动画的设置 * group.removedOnCompletion = NO; * group.fillMode = kCAFillModeForwards; */

     //添加动画
    [myLayer addAnimation:group forKey:@"MyLayerAnimation"];

CAKeyframeAnimation关键帧动画
CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值

属性说明:

values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧

path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略

keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的,CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation。Timing Function的作用:

Timing Function的会被用于变化起点和终点之间的插值计算.形象点说是Timing Function决定了动画运行的节奏(Pacing),比如是均匀变化(相同时间变化量相同),先快后慢,先慢后快还是先慢再快再慢.

时间函数是使用的一段函数来描述的,横座标是时间t取值范围是0.0-1.0,纵座标是变化量x(t)也是取值范围也是0.0-1.0 假设有一个动画,duration是8秒,变化值的起点是a终点是b(假设是透明度),那么在4秒处的值是多少呢? 可以通过计算为 a + x(4/8) * (b-a), 为什么这么计算呢?讲实现的时间映射到单位值的时候4秒相对于总时间8秒就是0.5然后可以得到0.5的时候单位变化量是 x(0.5), x(0.5)/1 = 实际变化量/(b-a), 其中b-a为总变化量,所以实际变化量就是x(0.5) * (b-a) ,最后4秒时的值就是 a + x(0.5) * (b-a),所以计算的本质是映射.

五种预定义的时间函数名字的常量变量分别为

  • kCAMediaTimingFunctionLinear
  • kCAMediaTimingFunctionEaseIn
  • kCAMediaTimingFunctionEaseOut
  • kCAMediaTimingFunctionEaseInEaseOut
  • kCAMediaTimingFunctionDefault

下图展示了前面四种Timing Function的曲线图,横座标表示时间,纵座标表示变化量,这点需要搞清楚(并不是平面座标系中xy).

ios开发中动画那点事_第1张图片

实例:分别使用属性values及path两种的效果;围绕的点视图块进行转动效果;

//values方式
-(void)animationValues
{

    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
    myView.backgroundColor = [UIColor cyanColor];
    [self.view addSubview:myView];


    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation];
    keyAnimation.keyPath = @"position";

    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(200, 100)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];


    keyAnimation.values = @[value1,value2,value3,value4,value5];
    keyAnimation.repeatCount = MAXFLOAT; //循环次数
    keyAnimation.removedOnCompletion = NO;
    keyAnimation.fillMode = kCAFillModeForwards;
    keyAnimation.duration = 4.0;
    keyAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    keyAnimation.delegate = self;
    [myView.layer addAnimation:keyAnimation forKey:nil];

}

//path方式
-(void)animationPath
{
    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
    myView.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:myView];

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    CGMutablePathRef path=CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(50, 100, 220, 180));

    animation.path=path;
    CGPathRelease(path);
    animation.repeatCount=MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 4.0f;
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.delegate=self;
    [myView.layer addAnimation:animation forKey:nil];
}

CAAnimationGroup(动画组)

动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行

属性说明:

animations:用来保存一组动画对象的NSArray

默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间

实例:创建一组动画效果,多个动画一起

-(void)animationGroup
{

    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(120, 350, 50, 50)];
    myView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:myView];

    //贝塞尔曲线路径
    UIBezierPath *movePath = [UIBezierPath bezierPath];
    [movePath moveToPoint:CGPointMake(50.0, 50.0)];
    [movePath addQuadCurveToPoint:CGPointMake(130, 350) controlPoint:CGPointMake(300, 100)];

    //关键帧动画(位置)
    CAKeyframeAnimation * posAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    posAnim.path = movePath.CGPath;
    posAnim.removedOnCompletion = YES;

    //缩放动画
    CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
    scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
    scaleAnim.removedOnCompletion = YES;

    //透明动画
    CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"alpha"];
    opacityAnim.fromValue = [NSNumber numberWithFloat:1.0];
    opacityAnim.toValue = [NSNumber numberWithFloat:0.1];
    opacityAnim.removedOnCompletion = YES;

    //动画组
    CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    animGroup.animations = [NSArray arrayWithObjects:posAnim, scaleAnim, opacityAnim, nil];
    animGroup.duration = 5;
    animGroup.autoreverses = NO;
    animGroup.removedOnCompletion = NO;
    animGroup.fillMode = kCAFillModeRemoved;

    [myView.layer addAnimation:animGroup forKey:nil];
}

CATransition(转场动画)

动画属性:

type:动画过渡类型

subtype:动画过渡方向

startProgress:动画起点(在整体动画的百分比)

endProgress:动画终点(在整体动画的百分比)

subtype:动画过渡方向(默认为nil,如果指定了filter,那么该属性无效,kCATransitionFromRight,kCATransitionFromLeft,kCATransitionFromTop,kCATransitionFromBottom;分别表示:过渡从右边、左边、顶部、底部 开始)

转场动画的类型(NSString *type),还有很多私有API类型

fade : 交叉淡化过渡

push : 新视图把旧视图推出去

moveIn: 新视图移到旧视图上面

reveal: 将旧视图移开,显示下面的新视图

cube : 立方体翻滚效果

oglFlip : 上下左右翻转效果

suckEffect : 收缩效果,如一块布被抽走

rippleEffect: 水滴效果

pageCurl : 向上翻页效果

pageUnCurl : 向下翻页效果

cameraIrisHollowOpen : 相机镜头打开效果

cameraIrisHollowClos : 相机镜头关闭效果

实例:两个动画效果,一个向上运动,一个向下运动的效果

//从下往上运动
-(void)animationTransition
{
    //y点就是当要运动后到的Y值

    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height-250, self.view.bounds.size.width, 250)];
    myView.backgroundColor = [UIColor redColor];
    [self.view addSubview:myView];

    CATransition *animation = [CATransition animation];
    animation.duration = 1;
    animation.timingFunction = UIViewAnimationCurveEaseInOut;
    animation.fillMode = kCAFillModeForwards;
    animation.type = kCATransitionMoveIn;
    animation.subtype = kCATransitionFromLeft;
    //添加动画
    [myView.layer addAnimation:animation forKey:nil];
}

//从上往下运动
-(void)animationPushTransition
{
    //y点就是当要运动后到的Y值

    UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 250)];
    myView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:myView];


    CATransition *animation = [CATransition animation];
    animation.duration = 4.0;
    animation.timingFunction = UIViewAnimationCurveEaseInOut;
    animation.fillMode = kCAFillModeForwards;
    animation.type = kCATransitionPush;
    animation.subtype = kCATransitionFromBottom;

    //添加动画
    [myView.layer addAnimation:animation forKey:nil];

}

有需要源码的小伙伴请戳这里哦!

你可能感兴趣的:(ios,动画,ios开发)