CoreAnimation VS Facebook's Pop

一、作用对象对比


CoreAnimation 只能作用于 CALayer;而Pop Animation可以是任意基于NSObject的对象;
CALayer补充:结构跟UIView的subView一样,都是一个树形的结构
重绘机制:当调用setNeedsDisplay的时候会重新调用render方法,而CALayer实际是维护个三个模型的树形结构,一个是渲染树,一个是呈现树,还有一个是当前模型树:
  • 模型树(Model Tree)直接创建的或者通过UIView获得的(view.layer)用于显示的图层树,称之为模型树(Model Tree);
    模型树的背后还存在两份图层树的拷贝,一个是呈现树(Presentation Tree),一个是渲染树(Render Tree).

  • 呈现树(Presentation Tree),呈现树可以通过普通layer(其实就是模型树)的layer.presentationLayer获得,模型树则可以通过layer.modelLayer属性获得。当给一个CALayer添加动画时,动画其实没有改变这个layer的实际属性,取而代之,系统会创建一个Model layer的复制品:Presentation Layer;Presentation Layer的属性值和动画运行过程中界面上看到的是一致的.Pop Animation应用于CALayer时,在动画运行的任何时刻,layer和其presentationLayer的相关属性值始终保持一致,而Core Animation做不到。

  • 渲染树(Render Tree),渲染树是私有的,你无法访问到,渲染树是对呈现树的数据进行渲染,为了不阻塞主线程,渲染的过程是在单独的进程或线程中进行的,所以Animation的动画并不会阻塞主线程.

我们在写动画时,通常会设置 removedOnCompletion = NO;设置 fillMode 为kCAFillModeForwards。这是因为系统会在duration 后自动销毁这个 layer 的 Presentation Layer ,只留下 Model Layer,不设置的话动画结束后会回到初始状态。

二、工作机制对比


Core Animation 工作机制
每当我们创建并添加动画到 layer 时,QuartzCore 框架就会把动画的参数打包好,然后通过处理器发送给名为 backboardd 的进程处理程序。你的应用也会发送当前展示在屏幕上的每一个 layer 的信息。
backboardd 会处理 layer 的结构体系然后通过 OpenGL 绘制出来。backboardd 使得动画的每一帧都可以在你的应用中完全独立。你的应用完全不会参与动画的绘制,这些绘制完全独立于你的应用进程。这意味着你可以继续在主线程做其他事情,并且不会影响到 CAAnimation 的性能。如果阻塞了主线程,或者你在调试器中暂停了你的程序,动画还是会继续执行。
POP 工作机制
POP 本质上是基于定时器的动画库,使用每秒 60 频率的定时器 CADisplayLink,使得动画刷新绘制频率与屏幕刷新频率一致。
一旦定时器刷新,动画库计算动画的进程,这意味着动画库会计算 layer 的属性,如 bound,opactiy,transform 等。然后动画库提供最新计算的值给有动画的 layer (或者其他对象)。最主要的区别是,layer 的状态将会在这种情况下改变。
由于 layer 的一些参数已经被改变,应用必须通过处理器通知 backboardd 进程处理这些变化。当 backboardd 接收到变化通知,它将在屏幕上重绘。这意味着,应用中做的每一个动画帧都会传送数据到 backboardd
由于 POP 是基于定时器定时刷新添加动画的原理,那么如果将动画库运行在主线程上,会由于线程阻塞的问题导致动画效果出现卡顿、不流畅的情况。更为关键的是,你不能将动画效果放在子线程,因为你不能将对 view 和 layer 的操作放到主线程之外。
- (void)viewDidLoad {
    [super viewDidLoad];
    CABasicAnimation *rotationAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotationAnim.toValue = @(M_PI);
    rotationAnim.duration = 2;
    rotationAnim.repeatCount = 20;
    [self.blueView.layer addAnimation:rotationAnim forKey:nil];
      
    POPBasicAnimation *popAnim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];
    popAnim.toValue = @(M_PI);
    popAnim.duration = 2;
    popAnim.repeatCount = 20;
    popAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    [self.yellowView.layer pop_addAnimation:popAnim forKey:nil];
    
    [self performSelector:@selector(causeMainThread) withObject:nil afterDelay:1];
}

-(void)causeMainThread
{
    // 即便线程发生死锁,CoreAnimation也会继续执行
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        NSLog(@"111");
    });
//    [NSThread sleepForTimeInterval:0.25];
//    [self performSelector:@selector(causeMainThread) withObject:nil afterDelay:1];
}

POP 受主线程阻塞的影响很大,因此,在使用过程中,应避免在有可能发生主线程阻塞的情况下使用 POP ,避免制作卡顿的动画效果,产生不好的用户体验。

三、使用效果对比


Pop 提供了很多类似于 CoreAnimation 的效果。在技术选择上,如果只是简单的 UIView 属性的动画则选择 [UIView animationWith...];如果需要CALayer做一些比较复杂的效果,但又不想引入第三方动画库,在执行效率上要求高,则首选CoreAnimation;但如果要求展现一些“果冻效果”,Pop 的 POPSpringAnimation 会比CoreAnimation 在参数调整上更简便易用。
CoreAnimation 自带的弹簧效果,从 iOS 7 开始被广泛应用在系统动画中。自 iOS 8 开始,Apple 公开了 Spring Animation 的 API,开发者也可以使用简单的代码创建这类动画效果:
+ (void)animateWithDuration:(NSTimeInterval)duration
                      delay:(NSTimeInterval)delay
     usingSpringWithDamping:(CGFloat)dampingRatio
      initialSpringVelocity:(CGFloat)velocity
                    options:(UIViewAnimationOptions)options
                 animations:(void (^)(void))animations
                 completion:(void (^)(BOOL finished))completion
而 CASpringAnimation 是iOS9才引入的动画类,它继承于CABaseAnimation
CASpringAnimation 参数说明:
  • mass: 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
  • stiffness: 刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
  • damping: 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
  • initialVelocity:初始速率,动画视图的初始速度大小
    速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反
  • settlingDuration: 结算时间,返回弹簧动画到停止时的估算时间,根据当前的动画参数估算,通常弹簧动画的时间使用结算时间比较准确
POPSpringAnimation 参数说明:
  • springBounciness 反弹-影响动画作用的参数的变化幅度
  • springSpeed 速度
  • dynamicsTension 拉力-影响回弹力度以及速度
  • dynamicsFriction 摩擦力-如果开启,动画会不断重复,幅度逐渐削弱,直到停止。
  • Mass 质量-细微的影响动画的回弹力度以及速度
实现同样的“果冻效果”,POPSpringAnimation 甚至只设置 springBounciness 一项就可以展现非常棒的效果,而CASpringAnimation则需要调整damping,mass 等多项参数才能达到同样效果。

演示&&讲解部分:

DEMO1 - CA和Pop线程阻塞对比


DEMO2 - POPSpringAnimation和CASpringAnimation效果对比


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

推荐阅读更多精彩内容