关于隐式动画的一些笔记

什么是隐式动画?

首先为 view 的根 layer 添加一个 subLayer

    CALayer *testLayer = [CALayer layer];
    testLayer.frame = CGRectMake(50, 50, 100, 100);
    testLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:testLayer];
    self.testLayer = testLayer;

然后尝试修改它的颜色

    self.testLayer.backgroundColor = [UIColor blueColor].CGColor;

当改变了 CALayer 的一个可做动画的属性
它并不是立刻在屏幕上体现出来
它是从先前的值平滑过渡到新的值(从红色渐变到了蓝色)
这一切都是默认的行为,我们不需要做额外的操作。

这其实就是隐式动画
之所以叫隐式是因为我们并没有指定任何动画的类型
我们仅仅改变了一个属性
然后 Core Animation 来决定如何并且何时去做动画
当然 Core Animaiton 同样支持显式动画

但当改变一个属性 Core Animation 是如何判断动画类型和持续时间的呢?
实际上动画执行的时间取决于当前事务的设置,动画类型取决于图层行为

事务 实际上是 Core Animation 用来包含一系列属性动画集合的机制
任何用指定事务去改变可以做动画的图层属性都不会立刻发生变化
而是当事务一旦提交的时候开始用一个动画过渡到新值

事务是通过 CATransaction 类来做管理
这个类的设计有些奇怪
不像你从它的命名预期的那样去管理一个简单的事务
而是管理了一叠你不能访问的事务
CATransaction 没有属性或者实例方法
并且也不能用 +alloc-init 方法创建它
但是可以用 +begin+commit 分别来入栈或者出栈。

任何可以做动画的图层属性都会被添加到栈顶的事务
你可以通过 +setAnimationDuration: 方法设置当前事务的动画时间
或者通过 +animationDuration 方法来获取值(默认0.25秒)。

Core Animation 在每个 run loop 周期中自动开始一次新的事务
即使你不显式的用 [CATransaction begin] 开始一次事务
任何在一次 run loop 循环中属性的改变都会被集中起来
然后做一次0.25秒的动画


修改隐式动画

于是我么可以尝试使用Core Animation来修改动画的属性
我们可以用当前事务的+setAnimationDuration:方法来修改动画时间
但在这里我们首先起一个新的事务
于是修改时间就不会有别的副作用
因为修改当前事务的时间可能会导致同一时刻别的动画(如屏幕旋转)
所以最好还是在调整动画之前压入一个新的事务

- (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.testLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
    //commit the transaction
    [CATransaction commit];
}

UIView 有两个方法

+beginAnimations:context:+commitAnimations
这与
CATransaction+begin+commit方法类似
实际上在+beginAnimations:context:+commitAnimations之间所有视图或者图层属性的改变而做的动画都是由于设置了CATransaction的原因

在iOS4中,苹果对 UIView 添加了一种基于 block 的动画方法:+animateWithDuration:animations:
这样写对做一堆的属性动画在语法上会更加简单
但实质上它们都是在做同样的事情

CATransaction+begin+commit方法在+animateWithDuration:animations:内部自动调用
这样block中所有属性的改变都会被事务所包含
这样也可以避免开发者由于对+begin+commit匹配的失误造成的风险


完成块

基于 UIView 的 block 的动画允许你在动画结束的时候提供一个完成的动作
CATranscation 接口提供的 +setCompletionBlock: 方法也有同样的功能

- (IBAction)changeColor
{
    //begin a new transaction
    [CATransaction begin];
    //set the animation duration to 1 second
    [CATransaction setAnimationDuration:1.0];
    //add the spin animation on completion
    [CATransaction setCompletionBlock:^{
        //rotate the layer 90 degrees
        CGAffineTransform transform = self.colorLayer.affineTransform;
        transform = CGAffineTransformRotate(transform, M_PI_2);
        self. testLayer.affineTransform = transform;
    }];
    //randomize the layer background color
    CGFloat red = arc4random() / (CGFloat)INT_MAX;
    CGFloat green = arc4random() / (CGFloat)INT_MAX;
    CGFloat blue = arc4random() / (CGFloat)INT_MAX;
    self. testLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
    //commit the transaction
    [CATransaction commit];
}

注意旋转动画要比颜色渐变快得多
这是因为完成块是在颜色渐变的事务提交并出栈之后才被执行
于是,用默认的事务做变换,默认的时间也就变成了0.25秒

另一篇讨论 View 的根 layer 为什么没有动画

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

推荐阅读更多精彩内容