CoreAnimation简介
- CoreAnimation(核心动画)是一组丰富,强大的API,用很少的代码量就能实现炫酷的动画.
- Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程.
- Core Animation可以用在Mac OS X和iOS平台.
- Core Animation是直接作用在CALayer上的.
使用方法和功能
要使用核心动画必须初始化一个CAAnimation对象,并设置动画相关属性,
箭头表示继承.CAAnimationGroup是组合动画.CATransition是转场动画.CAPropetyAnimation是一个抽象类,本身不能对layer进行操作,它包含2个子类CABasicAnimation(基本动画)和CAKeyframeAnimation(关键帧)
实例讲解CoreAnimation各个子类
1.CABasicAnimation
以上的动画就是利用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没有设置的时候,各个关键帧的时间是平分的.
上图是通过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
转场动画可以用在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
组合动画就是把各种类型的动画放到一起执行,在别的篇目中写过这里就不再赘述组合动画地址