Swift开发:iOS那些简单的动画

这篇博客详细介绍了在Swift中使用Core Animation进行动画开发,包括CABasicAnimation、CAKeyframeAnimation、CATransition和CAAnimationGroup的使用,以及如何实现各种动画效果。同时还提供了相关Demo的GitHub链接。
摘要由CSDN通过智能技术生成
 
 

关于 Core Animation

Core Animation是一组非常强大的动画处理API,使用它能做出很多优雅的动画效果。能用的动画类有4个子类:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup

开发步骤:

  1. 初始化一个动画对象(CAAnimation)并设置一些动画相关属性.

  2. 添加动画对象到层(CALayer)中,开始执行动画.

CALayer中很多属性都可以通过CAAnimation实现动画效果, 包括opacity, position, transform, bounds, contents等,具体可以在API文档中查找

通过调用CALayer的addAnimation:forKey:增加动画到层(CALayer)中,这样就能触发动画了.通过调用removeAnimationForKey:可以停止层中的动画.

注:Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程.

创建动画时你可能用到的属性

属性解读
Autoreverses设定这个属性为 YES 时,在它到达目的地之后,动画的返回到开始的值,代替了直接跳转到开始的值,过渡平滑
Duration设定开始值到结束值花费的时间。期间会被速度的属性所影响
RemovedOnCompletion这个属性默认为 YES,在指定的时间段完成后,动画就自动的从层上移除了。
FillMode这个属性一般和 RemovedOnCompletion 配合使用,保持动画状态。其中kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态.此时将RemovedOnCompletion设为NO
Speed默认的值为 1.0.如果你改变这个值为 2.0,动画会用 2 倍的速度播放。这样的影响就是使持续时间减半。如果你指定的持续时间为 6 秒,速度为 2.0,动画就会播放 3 秒钟即一半的持续时间。
RepeatCount默认的是 0,动画只会播放一次。如果指定一个无限大的重复次数,使用 MAXFLOAT 。这个不应该和 repeatDration 属性一块使用
RepeatDuration这个属性指定了动画应该被重复多久。动画会一直重复,直到设定的时间用完。同上它不应该和 repeatCount 一起使用
FromValue设置动画的初始值
ToValue设置动画的到达值
TimingFunction控制动画运行的节奏. kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉 kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开 kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地 kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
BeginTime可以用来设置动画延迟执行时间,若想延迟1s,就设置为CACurrentMediaTime()+1,CACurrentMediaTime()为图层的当前时间

巧妙的运用这些可以属性实现很棒的动画效果,比如下面:用CABasicAnimation实现的动画

CABasicAnimation动画

简单的呼吸和摇摆动画

animation.gif

简单的代码

 1.呼吸动画
    CABasicAnimation *animation =[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.fromValue = [NSNumber numberWithFloat:1.0f];
    animation.toValue = [NSNumber numberWithFloat:0.0f];
    animation.autoreverses = YES;    //回退动画(动画可逆,即循环)
    animation.duration = 1.0f;
    animation.repeatCount = MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;//removedOnCompletion,fillMode配合使用保持动画完成效果
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [self.alphaTagButton.layer addAnimation:animation forKey:@"aAlpha"];  

2.摇摆动画
    //设置旋转原点
    self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
    CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    //角度转弧度(这里用1,-1简单处理一下)
    rotationAnimation.toValue = [NSNumber numberWithFloat:1];
    rotationAnimation.fromValue = [NSNumber numberWithFloat:-1];
    rotationAnimation.duration = 1.0f;
    rotationAnimation.repeatCount = MAXFLOAT;
    rotationAnimation.removedOnCompletion = NO;
    rotationAnimation.autoreverses = YES;
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    rotationAnimation.fillMode = kCAFillModeForwards;
    [self.sharkTagButton.layer addAnimation:rotationAnimation forKey:@"revItUpAnimation"];

陀螺仪&加速仪的动画

ps:好吧 这个属于乱入,和上面的摇摆动画差不多的效果,只是这个是手动的 哈哈

3、陀螺仪&加速仪的动画
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.deviceMotionUpdateInterval = 1.0f/100.0f; //1秒100次
    self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
    [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
        if(fabs(motion.attitude.roll)<1.0f)
        {
            [UIView animateWithDuration:0.6 animations:^{
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(-(motion.attitude.roll), 0, 0, 1);
            }];
        }else if (fabs(motion.attitude.roll)<1.5f)
        {
            [UIView animateWithDuration:0.6 animations:^{
                int s;
                if (motion.attitude.roll>0)
                {
                    s=-1;
                }else
                {
                    s = 1;
                }
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(s*M_PI_2, 0, 0, 1);
            }];
        }
        if ((motion.attitude.pitch)<0)
        {
            [UIView animateWithDuration:0.6 animations:^{
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
            }];
        }

    }];

Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo



CATransition之简单的转场动画

CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。

属性解读
type动画过渡类型
subtype动画过渡方向
  • 常用动画类型:
type的值解读对应常量
fade淡入淡出kCATransitionFade
push推挤kCATransitionPush
reveal揭开kCATransitionReveal
moveIn覆盖kCATransitionMoveIn
cube立方体私有API
suckEffect吮吸私有API
oglFlip翻转私有API
rippleEffect波纹私有API
pageCurl反翻页私有API
cameraIrisHollowOpen开镜头私有API
cameraIrisHollowClose关镜头私有API

注:私有API只能通过字符串使用哈


  • 过渡方向参数:
subtype的值解读
kCATransitionFromRight从右转场
kCATransitionFromLeft从左转场
kCATransitionFromBottom从下转场
kCATransitionFromTop从上转场

简单的CATransition动画


CATransitionDemo2.gif
-(void)animationWithType:(NSString*)type
{

    //- 创建一个转场动画:
    CATransition *transition = [CATransition animation];
    transition.repeatCount = 5;

    //    - 确定动画类型:
    transition.type = type;

    //    - 确定子类型(方向等)
    transition.subtype = kCATransitionFromLeft;

    //    - 确定动画时间
    transition.duration = 1;

    //    - 添加动画
    [self.imageView.layer addAnimation:transition forKey:nil];

}

使用时只用传你的想要的动画类型就好,私有API只能通过字符串使用哈。

[self animationWithType:self.dataArray[indexPath.row]];

DEMO地址:https://github.com/yongliangP/CATransitionDemo


---20160908更新


CAKeyframeAnimation

先看图,就是那个在跑的小圆球,为了方便,把动画集成在了一个Demo里了


ScreenShotDemo2.gif
  • 1 .简单介绍

    CAKeyframeAnimation是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值,是一种更灵活的动画方式。

  • 2 .属性介绍

属性解读
valuesNSArray对象,里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
path可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略
keyTimes可以为对应的关键帧指定对应的时间点,其取值范围为[0,1],keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的
  • 3 .实现
    • 3.1 values方式实现
-(void)setUpCAKeyframeAnimationUseValues
{

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];

    animation.keyPath = @"position";

    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];

    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, 50)];

    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, kWindowHeight-50)];

    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(50, kWindowHeight-50)];

    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];

    animation.values = @[value1,value2,value3,value4,value5];
    animation.repeatCount = MAXFLOAT;

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

    animation.duration = 6.0f;

    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    [self.keyButton.layer addAnimation:animation forKey:@"values"];

}
    • 3.2 path方式实现
-(void)setUpCAKeyframeAnimationUsePath
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];

    animation.keyPath = @"position";

    CGMutablePathRef path = CGPathCreateMutable();

    //矩形线路
    CGPathAddRect(path, NULL, CGRectMake(50,50, kWindowWidth - 100,kWindowHeight - 100));

    animation.path=path;

    CGPathRelease(path);

    animation.repeatCount = MAXFLOAT;

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

    animation.duration = 10.0f;

    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    [self.keyButton.layer addAnimation:animation forKey:@"path"];


}
    • 3.3 keyTimes演示
-(void)setUpCAKeyframeAnimationUsekeyTimes
{

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
//    animation.keyPath = @"transform.translation.x";
    animation.keyPath = @"position.x";
    animation.values = @[@0, @20, @-20, @20, @0];
    animation.keyTimes = @[ @0, @(1 / 6.0), @(3 / 6.0), @(5 / 6.0), @1 ];
    animation.duration = 0.5;
    animation.additive = YES;
    [self.sharkTagButton.layer addAnimation:animation forKey:@"keyTimes"];

}

---20160921更新


CAAnimationGroup

看图,就是那个下方的小长方形,简单实现


ScreenShotGroupDemo.gif

动画组,顾名思义就是动画的组合,具体动画可以参考上文,不同的脑洞会出现不同的化学反应。

简单示例:

    CABasicAnimation * animationScale = [CABasicAnimation animation];
    animationScale.keyPath = @"transform.scale";
    animationScale.toValue = @(0.1);

    CABasicAnimation *animationRota = [CABasicAnimation animation];
    animationRota.keyPath = @"transform.rotation";
    animationRota.toValue = @(M_PI_2);

    CAAnimationGroup * group = [[CAAnimationGroup alloc] init];
    group.duration = 3.0;
    group.fillMode = kCAFillModeForwards;
    group.removedOnCompletion = NO;
    group.repeatCount = MAXFLOAT;

    group.animations = @[animationScale,animationRota];
    [self.groupButton.layer addAnimation:group forKey:nil];

Demo传送门

附:关于keyPath你可能用到的属性

属性解读
transform.rotation.x围绕x轴翻转。y,z同理 参数:角度
transform.rotation默认围绕z轴
transform.scale.xx方向缩放。y,z同理
transform.scale所有方向缩放
transform.translation.xx轴方向移动,参数:x轴上的坐标。y,z同理
transform.translation移动到的点
zPosition平面的位置
opacity透明度
backgroundColor背景颜色 参数:颜色 (id)[[UIColor redColor] CGColor]
cornerRadiuslayer圆角
borderWidth边框宽度
bounds大小 参数:CGRect
contents内容 参数:CGImage
contentsRect可视内容 参数:CGRect 值是0~1之间的小数
position位置,效果和transform.rotation差不多
shadowColor阴影颜色
shadowOffset阴影偏移
shadowOpacity阴影透明度
shadowRadius阴影角度

照例放Demo
Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo



作者:iceMaple
链接:http://www.jianshu.com/p/a098f6e3617f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值