Core Animation 的隐式动画
2015-10-22 17:04
531 查看
场景重现:为什么UIView或者CALayer改变他们相关属性,他们就会平缓的做些动画,这时你并没有调用相关动画代码,想过这个问题没?
那我们来看看系统究竟帮我们做了哪些东西。
如果你自己设置了动画类型和动画时间,表现出来就是你指定的动画,如果没有,那么系统会自动帮我们做了动画类型和动画时间(这就是隐式动画)。
问题有来了,什么决定了动画时间和动画类型。
1、动画时间: 当前”事务” 决定的 ==>“事务“是通过CATransaction类来做管理。
2、动画类型:由图层的行为决定的。
note:CATransaction概念
CATransaction没有属性或者实例方法,并且也不能用+alloc和-init方法创建它。但是可以用+begin和+commit分别来入栈或者出栈
隐式动画真正背后执行的原因:
Core Animation在每个run loop周期中自动开始一次新的事务(run loop是iOS负责收集用户输入,处理定时器或者网络事件并且重新绘制屏幕的东西),即使你不显式的用[CATransaction begin]开始一次事务,任何在一次run loop循环中属性的改变都会被集中起来,然后做一次0.25秒的动画。
如果你不用系统的动画模式,要自定义,最原始的样子就是下面
上面讨论所有的问题,都是动画时间相关的,还有个影响动画的因素,刚才的第二点:动画类型(由图层决定了)
运行程序,你会发现当按下按钮,图层颜色瞬间切换到新的值,而不是之前平滑过渡的动画。发生了什么呢?
先给结论:
1、是给UIView做的动画,那么一定要用UIView层的动画模式(UIView有两个方法,+beginAnimations:context:和+commitAnimations)。
2、是给CALayer做动画,那么一定用CATransaction begin相关的方法。
原因就是上面程序出现的问题:UIView关联的图层禁用了隐式动画,造成了动画没有。
再深入一点,隐式动画是如何被UIKit禁用掉呢?
解决这个问题,先看看这个系统大概是如何实现隐式动画?
CALayer的属性被修改时候,layer首先检测它是否有委托,
1、有代理对象,它会调用-actionForKey:方法,
2、没有代理对象,去找图层动画的action(以那种动画展现),它最后最后会调用,defaultActionForKey:这个应该就是隐式动画效果
很显然,UIView做了layer的代理,再UIView内部实行了-actionForKey:方法,估计如果不是调用UIView的动画方法时,实现的协议方法actionForKey:里面返回一个nil,如果调用UIView的自己的动画方法,就返回值,产生了动画。
上面也可以总结一点:UIKit建立在Core Animation(默认对所有东西都做动画)之上,所有Core Animation的动画方法,再UIKit层都有对应的。
比如:
1、UIView有两个方法,+beginAnimations:context:和+commitAnimations,和CATransaction的+begin和+commit方法类似。
2、 UIView的block的动画允许你在动画结束的时候提供一个完成的动作。CATranscation接口提供的+setCompletionBlock:方法也有同样的功能。
在上面讲系统大概是如何实现隐式动画,说到”没有代理对象,去找图层动画的action(以那种动画展现)”,如果我不想用系统提供的动画效果,有没有其他的动画效果可以执行。
上面就做到了自定义action(动画效果)。
注意:这里要提醒大家:CATransition和CATransaction的区别。
这个就能看出CATransition和CATransaction真正的区别了吧。
只要记住后面单词的区别:
action结尾的就是开始动画、提交动画(action行为的事情)
sition结尾的就是名词,就是自定义动画相关
8bde
的属性,
那我们来看看系统究竟帮我们做了哪些东西。
如果你自己设置了动画类型和动画时间,表现出来就是你指定的动画,如果没有,那么系统会自动帮我们做了动画类型和动画时间(这就是隐式动画)。
问题有来了,什么决定了动画时间和动画类型。
1、动画时间: 当前”事务” 决定的 ==>“事务“是通过CATransaction类来做管理。
2、动画类型:由图层的行为决定的。
note:CATransaction概念
CATransaction没有属性或者实例方法,并且也不能用+alloc和-init方法创建它。但是可以用+begin和+commit分别来入栈或者出栈
隐式动画真正背后执行的原因:
Core Animation在每个run loop周期中自动开始一次新的事务(run loop是iOS负责收集用户输入,处理定时器或者网络事件并且重新绘制屏幕的东西),即使你不显式的用[CATransaction begin]开始一次事务,任何在一次run loop循环中属性的改变都会被集中起来,然后做一次0.25秒的动画。
如果你不用系统的动画模式,要自定义,最原始的样子就是下面
- (IBAction)changeColor { //begin a new transaction [CATransaction begin]; //set the animation duration to 1 second [CATransaction setAnimationDuration:1.0]; //randomize the layer background color CGFloat red = arc4random() / (CGFloat)INT_MAX; CGFloat green = arc4random() / (CGFloat)INT_MAX; CGFloat blue = arc4random() / (CGFloat)INT_MAX; self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor; //commit the transaction [CATransaction commit]; }
上面讨论所有的问题,都是动画时间相关的,还有个影响动画的因素,刚才的第二点:动画类型(由图层决定了)
动画类型(由图层决定)
先上代码,让大家看看问题。@interface ViewController () @property (nonatomic, weak) IBOutlet UIView *layerView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.layerView.layer.backgroundColor = [UIColor blueColor].CGColor;//这里直接给view的layer层设置了颜色 } - (IBAction)changeColor { //begin a new transaction [CATransaction begin]; //set the animation duration to 1 second [CATransaction setAnimationDuration:1.0]; //randomize the layer background color CGFloat red = arc4random() / (CGFloat)INT_MAX; CGFloat green = arc4random() / (CGFloat)INT_MAX; CGFloat blue = arc4random() / (CGFloat)INT_MAX; self.layerView.layer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor; //commit the transaction [CATransaction commit]; }
运行程序,你会发现当按下按钮,图层颜色瞬间切换到新的值,而不是之前平滑过渡的动画。发生了什么呢?
先给结论:
1、是给UIView做的动画,那么一定要用UIView层的动画模式(UIView有两个方法,+beginAnimations:context:和+commitAnimations)。
2、是给CALayer做动画,那么一定用CATransaction begin相关的方法。
原因就是上面程序出现的问题:UIView关联的图层禁用了隐式动画,造成了动画没有。
再深入一点,隐式动画是如何被UIKit禁用掉呢?
解决这个问题,先看看这个系统大概是如何实现隐式动画?
CALayer的属性被修改时候,layer首先检测它是否有委托,
1、有代理对象,它会调用-actionForKey:方法,
2、没有代理对象,去找图层动画的action(以那种动画展现),它最后最后会调用,defaultActionForKey:这个应该就是隐式动画效果
很显然,UIView做了layer的代理,再UIView内部实行了-actionForKey:方法,估计如果不是调用UIView的动画方法时,实现的协议方法actionForKey:里面返回一个nil,如果调用UIView的自己的动画方法,就返回值,产生了动画。
上面也可以总结一点:UIKit建立在Core Animation(默认对所有东西都做动画)之上,所有Core Animation的动画方法,再UIKit层都有对应的。
比如:
1、UIView有两个方法,+beginAnimations:context:和+commitAnimations,和CATransaction的+begin和+commit方法类似。
2、 UIView的block的动画允许你在动画结束的时候提供一个完成的动作。CATranscation接口提供的+setCompletionBlock:方法也有同样的功能。
在上面讲系统大概是如何实现隐式动画,说到”没有代理对象,去找图层动画的action(以那种动画展现)”,如果我不想用系统提供的动画效果,有没有其他的动画效果可以执行。
@interface ViewController () @property (nonatomic, weak) IBOutlet UIView *layerView; @property (nonatomic, weak) IBOutlet CALayer *colorLayer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //create sublayer self.colorLayer = [CALayer layer]; self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f); self.colorLayer.backgroundColor = [UIColor blueColor].CGColor; //add a custom action CATransition *transition = [CATransition animation]; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromLeft; self.colorLayer.actions = @{@"backgroundColor": transition}; //add it to our view [self.layerView.layer addSublayer:self.colorLayer]; } @end
上面就做到了自定义action(动画效果)。
注意:这里要提醒大家:CATransition和CATransaction的区别。
这个就能看出CATransition和CATransaction真正的区别了吧。
只要记住后面单词的区别:
action结尾的就是开始动画、提交动画(action行为的事情)
sition结尾的就是名词,就是自定义动画相关
8bde
的属性,
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Gifski:一个跨平台的高质量 GIF 编码器
- 模仿动画的放大缩小容器
- Android中ViewFlipper的使用及设置动画效果实例详解
- jQuery实现美观的多级动画效果菜单代码
- php判断GIF图片是否为动画的方法
- jQuery实现动画效果circle实例
- 浅析JavaScript动画
- js排序动画模拟-插入排序
- javascript+HTML5的Canvas实现Lab单车动画效果
- js实现按钮颜色渐变动画效果
- jQuery实现连续动画效果实例分析
- jQuery实现带有洗牌效果的动画分页实例
- jquery实现先淡出再折叠收起的动画效果