属性动画
-
CABasicAnimation
找到一篇很详细的CABasicAnimation使用总结
-
CAKeyframeAnimation
CAKeyframeAnimation用values
数组代替fromValue
和toValue
,里面的元素称为”关键帧“,动画对象会在指定的时间内,依次显示values
数组中的每一个关键帧。
path
属性:可以设置一个CGPathRef、CGMutabelPathRef,让图层按照路径轨迹移动,path
只对CALayer
的anchorPoint
和position
起作用,如果设置了path
,那么values
将被忽略。
keyTimes
:可以为对应的关键帧指定对一个你的时间点,其取值范围为0到1.0,keyTimes
中的每一个时间值都对应values
中的每一帧。如果没有设置keyTimes
,各个关键帧的时间是平分的。
rotationMode
属性,设置它为常量kCAAnimationRotateAuto
,图层将会根据曲线的切线自动旋转。
动画组
-
CABasicAnimation
和CAKeyframeAnimation
仅仅作用于单独的属性,而CAAnimationGroup
可以把这些动画组合在一起。CAAnimationGroup
是另一个继承于CAAnimation
的子类,它添加了一个animations
数组的属性,用来组合别的动画。
let groupAnimation = CAAnimationGroup()
groupAnimation.animations = [animation1,animation2]
groupAnimation.duration = 4.0
self.shipLayer.addAnimation(groupAnimation, forKey: nil)
过渡
- 有时候对于iOS应用程序来说,希望能通过属性动画来对比较难做动画的布局进行一些改变。比如交换一段文本和图片,或者用一段网格视图来替换,等等。属性动画只对图层的可动画属性起作用,所以如果要改变一个不能动画的属性(比如图片),或者从层级关系中添加或者移除图层,属性动画将不起作用。
于是就有了过渡的概念。过渡并不像属性动画那样平滑地在两个值之间做动画,而是影响到整个图层的变化。过渡动画首先展示之前的图层外观,然后通过一个交换过渡到新的外观。
为了创建一个过渡动画,我们将使用CATransition
,同样是另一个CAAnimation
的子类,和别的子类不同,CATransition
有一个type
和subtype
来标识变换效果。 -
type
属性是一个String
类型,可以被设置成如下类型:
kCATransitionFade
kCATransitionMoveIn
kCATransitionPush
kCATransitionReveal
除了这四种类型,可以通过一些别的方法来自定义过渡效果。默认的过渡类型是kCATransitionFade
,当你在改变图层属性之后,就创建了一个平滑的淡入淡出效果。
kCATransitionPush
创建了一个新的图层,从边缘的一侧滑动进来,把旧图层从另一侧推出去的效果。
kCATransitionMoveIn
从顶部滑动进入,但不像推送动画那样把老图层推走。
kCATransitionReveal
把原始的图层滑动出去来显示新的外观,而不是把新的图层滑动进入。 - 后面三种过渡类型都有一个默认的动画方向,它们都从左侧滑入,但是你可以通过
subtype
来控制它们的方向,提供了如下四种类型:
kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromTop
kCATransitionFromBottom - 过渡动画和之前的属性动画或者动画组添加到图层上的方式一致,都是通过
-addAnimation:forKey:
方法。但是和属性动画不同的是,对指定的图层一次只能使用一次CATransition。 -
隐式过渡
在自己创建的图层中对图层contents
图片做的改动都会自动附上淡入淡出的动画,但是对于视图关联的图层,或者是其他隐式动画的行为,这个特性依然是被禁用的。
-
对图层树的动画
CATransition
并不作用于指定的图层属性,可以在即使不能准确得知改变了什么的情况下对图层做动画,例如,在不知道UITableView
哪一行被添加或者删除的情况下,直接就可以平滑地刷新它,或者在不知道UIViewController
内部的视图层级的情况下对两个不同的实例做过渡动画。
为了确保CATransition
添加到的图层在过渡动画发生时不会在树状结构中被移除,一般来说,只需要将动画添加到被影响图层的superlayer
。
-
自定义动画
苹果通过UIView
的+transitionFromView:toView:duration:options:completion:
和+transitionWithView:duration:options:animations:
方法提供了Core Animation的过渡特性。但是这里的可用的过渡选项和CATransition
的type
属性提供的常量完全不同。UIView
过渡方法中options
参数可以由如下常量指定:
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown
UIViewAnimationOptionTransitionCrossDissolve
UIViewAnimationOptionTransitionFlipFromTop
UIViewAnimationOptionTransitionFlipFromBottom
CALayer
有一个-renderInContext:
方法,可以通过把它绘制到Core Graphics的上下文中捕获当前内容的图片,然后在另外的视图中显示出来。如果我们把这个截屏视图置于原始视图之上,就可以遮住真实视图的所有变化,于是重新创建了一个简单的过渡效果。
用renderInContext:
创建自定义过渡效果
@IBAction func start(sender: UIButton) {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, 0.0)
self.view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let coverImage = UIGraphicsGetImageFromCurrentImageContext()
//insert snapshot view in front of this one
let coverView = UIImageView(image: coverImage)
coverView.frame = self.view.bounds
self.view.addSubview(coverView)
//update the view (we'll simply randomize the layer background color)
let red = CGFloat(arc4random()) / CGFloat(INT_MAX)
let green = CGFloat(arc4random()) / CGFloat(INT_MAX)
let blue = CGFloat(arc4random()) / CGFloat(INT_MAX)
self.view.backgroundColor = UIColor(red: red, green: green, blue: blue, alpha: 1.0)
//perform animation (anything you like)”
UIView.animateWithDuration(1.0, animations: ({
var transform = CGAffineTransformIdentity
transform = CGAffineTransformMakeScale(0.01, 0.01)
transform = CGAffineTransformRotate(transform,CGFloat(M_PI_2))
coverView.transform = transform
coverView.alpha = 0.0
}), completion: { (finished:Bool) -> Void in coverView.removeFromSuperview()}
)
}
这里有个警告:
-renderInContext:
捕获了图层的图片和子图层,但是不能对子图层正确地处理变换效果,而且对视频和OpenGL内容也不起作用。但是用CATransition
,或者用私有的截屏方式就没有这个限制了。
在动画过程中取消动画
- 可以用
-addAnimation:forKey:
方法中的key
参数来在添加动画之后检索一个动画,使用如下方法:- (CAAnimation *)animationForKey:(NSString *)key
;但并不支持在动画运行过程中修改动画,所以这个方法主要用来检测动画的属性,或者判断它是否被添加到当前图层中。为了终止一个指定的动画,你可以用如下方法把它从图层移除掉:- (void)removeAnimationForKey:(NSString *)key
,或者移除所有动画:- (void)removeAllAnimations
。
动画一旦被移除,图层的外观就立刻更新到当前的模型图层的值。一般说来,动画在结束之后被自动移除,除非设置removedOnCompletion
为NO
,如果你设置动画在结束之后不被自动移除,那么当它不需要的时候你要手动移除它;否则它会一直存在于内存中,直到图层被销毁。
-animationDidStop:finished:
方法中的flag
参数表明了动画是自然结束还是被打断,如果被打断,它会打印NO
,如果允许它完成,它会打印YES
。
网友评论