Core Animation 的隐式动画
来源:互联网 发布:ubuntu搭建openstack 编辑:程序博客网 时间:2024/05/17 12:21
场景重现:为什么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秒的动画。
如果你不用系统的动画模式,要自定义,最原始的样子就是下面
- (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结尾的就是名词,就是自定义动画相关的属性,
- Core Animation 的隐式动画
- Core Animation(四)隐式动画
- Core Animation - 事务之隐式动画
- 7.隐式动画---iOS-Core-Animation-Advanced-Techniques
- iOS-Core-Animation之七----隐式动画
- Core Animation 下提供的动画
- Core Animation核心动画的使用
- Core Animation(五)显式动画
- Core Animation 动画
- Core Animation CALayer动画
- ios Core Animation 动画
- 核心动画Core Animation
- Core Animation动画技术
- Core Animation 核心动画
- 核心动画(Core Animation)
- 核心动画 Core Animation
- 核心动画(Core Animation)
- Core Animation 动画
- PHP框架CodeIgniter入门使用(2)
- JDBC-连接mysql查询数据时中文为空解决办法
- eclipse 中导入RecyclerView
- Xcode7 The resource could not be loaded because the App Transport Security
- C++ 与js 2
- Core Animation 的隐式动画
- TreeSet --实现学生按年龄大小和姓名排序
- JVM自带的监控工具
- 远程设置Mac 黑名单和踢下线实现
- 数据库连接池
- 【NOIP 2002】字串变换
- PHP Session 登陆 验证
- mysql c
- leetcode Set Matrix Zeroes