系统讲解Swift 3.0核心动画(CoreAnimation)

CoreAnimation简介

  • CoreAnimation(核心动画)是一组丰富,强大的API,用很少的代码量就能实现炫酷的动画.
  • Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程.
  • Core Animation可以用在Mac OS X和iOS平台.
  • Core Animation是直接作用在CALayer上的.

使用方法和功能

123.png

要使用核心动画必须初始化一个CAAnimation对象,并设置动画相关属性,
箭头表示继承.CAAnimationGroup是组合动画.CATransition是转场动画.CAPropetyAnimation是一个抽象类,本身不能对layer进行操作,它包含2个子类CABasicAnimation(基本动画)和CAKeyframeAnimation(关键帧)

实例讲解CoreAnimation各个子类

1.CABasicAnimation

basic.gif

以上的动画就是利用CABasicAnimation进行实现的.
CABasicAnimation能实现诸多的动画,移动,旋转,缩放....下面KeyPath所涉及的都能实现

        /*
         一些常用的animationWithKeyPath值的总结
         transform.scale    比例转化
         transform.scale.x  宽的比例
         transform.scale.y  高的比例
         transform.rotation.x   围绕x轴旋转
         transform.rotation.y   围绕y轴旋转
         transform.rotation.z   围绕z轴旋转
         cornerRadius   圆角的设置
         backgroundColor    背景颜色的变化
         bounds 大小,中心不变
         position   位置(中心点的改变)
         contents   内容(更换图片)
         opacity    透明度
         contentsRect.size.width    横向拉伸缩放
         */
        
        
        //心脏跳动
        imageView = UIImageView.init(frame: CGRect.init(x: 50, y: 80, width: 50, height: 50))
        imageView?.image = UIImage.init(named: "heart")
        self.view.addSubview(imageView!)
        //transform.scale   比例转化
        let baseAnimation = CABasicAnimation.init(keyPath: "transform.scale")
        baseAnimation.fromValue = NSNumber.init(value: 0.5)
        baseAnimation.toValue = NSNumber.init(value: 1.5)
        //一次持续的时间
        baseAnimation.duration = 1
        //重复次数
        baseAnimation.repeatCount = MAXFLOAT
        
        /*
         控制动画运行的节奏
         kCAMediaTimingFunctionLinear (线性):匀速,给你一个相对静态的感觉
         kCAMediaTimingFunctionEaseIn (渐进):动画缓慢进入,然后加速离开
         kCAMediaTimingFunctionEaseOut (渐出):动画全速进入,然后减速的到达目的地
         kCAMediaTimingFunctionEaseInEaseOut (渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
         */
        baseAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseOut)
        
        imageView?.layer.add(baseAnimation, forKey: "xinzang")

        //风车
        let imageView1 = UIImageView.init(frame: CGRect.init(x: 150, y: 150, width: 50, height: 50))
        imageView1.image = UIImage.init(named: "fengche")
        self.view.addSubview(imageView1)
        //transform.rotation.z  围绕z轴旋转   transform.rotation.y  围绕y轴旋转  transform.rotation.x  围绕x轴旋转
        let baseAnimation1 = CABasicAnimation.init(keyPath: "transform.rotation.z")
        baseAnimation1.fromValue = NSNumber.init(value: 0)
        baseAnimation1.toValue = NSNumber.init(value: 2*M_PI)
        baseAnimation1.duration = 2
        baseAnimation1.repeatCount = MAXFLOAT
        imageView1.layer.add(baseAnimation1, forKey: "fengche")
        
        
        //箭头移动
        let imageView2 = UIImageView.init(frame: CGRect.init(x: 100, y: 200, width: 100, height: 100))
        imageView2.image = UIImage.init(named: "arrow")
        self.view.addSubview(imageView2)
        
        let baseAnimation2 = CABasicAnimation.init(keyPath: "position.x")
        baseAnimation2.fromValue = NSNumber.init(value: 0)
        baseAnimation2.toValue = NSNumber.init(value: 300)
        baseAnimation2.duration = 2
        //逆行动画
//        baseAnimation2.autoreverses = true
        baseAnimation2.repeatCount = MAXFLOAT
      
        //防止动画接收后回到初始状态
        
        baseAnimation2.isRemovedOnCompletion = false
        
        baseAnimation2.fillMode = kCAFillModeForwards
        
        //方法addAnimation:forKey:是将 CABasicAniamtion 对象进行了 copy 操作的。所以在将其添加到一个layer上之后,我们还是将其再次添加到另一个layer上的
        imageView2.layer.add(baseAnimation2, forKey: "pingyi")

2.CAKeyframeAnimation

  • CAKeyframeAnimation跟CABasicAnimation的区别是:
    CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值.
  • CAKeyframeAnimation属性解析:
    values:就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧 .
    path:如果你设置了path,那么values将被忽略.
    keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的.
KeyframeAnimation.gif

上图是通过CAKeyframeAnimation实现的,CABasicAnimation能实现的CAKeyframeAnimation也能实现,而且更具体和准确

         //抖动动画
        let imageView = UIImageView.init(frame: CGRect.init(x: 200, y: 250, width: 50, height: 50))
        imageView.image = UIImage.init(named: "购物车")
        self.view.addSubview(imageView)
        //摇一摇
        let shakeAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
        //设置晃动角度
        let angle = M_PI_4 / 2
        //设置关键帧动画的值
        shakeAnimation.values = [angle,-angle,angle]
        //设置关键帧动画每帧的执行时间,这里不设置也行,默认平均分配时间
        shakeAnimation.keyTimes = [NSNumber(value: 0), NSNumber(value: 0.5), NSNumber(value: 1)]
        //设置动画重复次数,默认为1次
        shakeAnimation.repeatCount = MAXFLOAT
        //设置动画执行效果
        shakeAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)]
        //设置相邻动画过渡方式
        shakeAnimation.calculationMode = kCAAnimationCubic
        //添加动画
        imageView.layer.add(shakeAnimation, forKey: nil)

        //轨迹动画
        let imageView = UIImageView.init(frame: CGRect.init(x: 200, y: 250, width: 50, height: 50))
        imageView.image = UIImage.init(named: "购物车")
        self.view.addSubview(imageView)
        let path = UIBezierPath()
        //设置动画的执行路径为一个M的形状
        path.move(to: CGPoint(x: 40, y: 300))
        path.addLine(to: CGPoint(x: 80, y: 150))
        path.addLine(to: CGPoint(x: 120, y: 300))
        path.addLine(to: CGPoint(x: 160, y: 150))
        path.addLine(to: CGPoint(x: 200, y: 300))
        let bezierAnimation = CAKeyframeAnimation(keyPath: "position")
        //由于CAKeyframeAnimation的path为CGPath,所以这里要转换一次
        bezierAnimation.path = path.cgPath
        //设置动画时间
        bezierAnimation.duration = 4
        //自动旋转layer角度与path相切
        bezierAnimation.rotationMode = kCAAnimationRotateAuto
        //设置动画重复次数
        bezierAnimation.repeatCount = MAXFLOAT
        //设置自动逆向
        bezierAnimation.autoreverses = true
        imageView.layer.add(bezierAnimation, forKey: nil)


        //心脏收缩
        let imageView = UIImageView.init(frame: CGRect.init(x: 200, y: 350, width: 50, height: 50))
        imageView.image = UIImage.init(named: "heart")
        self.view.addSubview(imageView)
        let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
        scaleAnimation.values = [0.0, 0.4, 0.8, 1.2, 1.6, 1.2, 0.8, 0.4, 0.0]
        scaleAnimation.duration = 2
        scaleAnimation.autoreverses = true
        scaleAnimation.repeatCount = MAXFLOAT
        imageView.layer.add(scaleAnimation, forKey: nil)

3.CATransition

CATransition.gif

转场动画可以用在View之间的切换动画,或者定义控制器之间的跳转动画,更改type属性即可更改过渡动画类型

        let VC = OtherViewController()
        
        /* 过渡效果类型:
         fade     //交叉淡化过渡(不支持过渡方向) kCATransitionFade
         push     //新视图把旧视图推出去  kCATransitionPush
         moveIn   //新视图移到旧视图上面   kCATransitionMoveIn
         reveal   //将旧视图移开,显示下面的新视图  kCATransitionReveal
         cube     //立方体翻滚效果
         oglFlip  //上下左右翻转效果
         suckEffect   //收缩效果,如一块布被抽走(不支持过渡方向)
         rippleEffect //滴水效果(不支持过渡方向)
         pageCurl     //向上翻页效果
         pageUnCurl   //向下翻页效果
         cameraIrisHollowOpen  //相机镜头打开效果(不支持过渡方向)
         cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)
         */
        
        let anima = CATransition.init()
        anima.type = kCATransitionReveal
        anima.subtype = kCATransitionFromRight
        anima.duration = 1.0
        anima.type = "push"
        
        UIApplication.shared.keyWindow?.layer.add(anima, forKey: nil)
        self.navigationController?.pushViewController(VC, animated: false)

4.CAAnimationGroup
组合动画就是把各种类型的动画放到一起执行,在别的篇目中写过这里就不再赘述组合动画地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容