iOS CoreAnimation专题——原理篇(一) CALayer与UIView之间的关系

本篇概览

这一篇中,我们将简单的探究动画原理(所以这一篇很多文字内容)。首先我们要知道我们在屏幕上看到的一切是如何被绘制出来的,我们将介绍CALayer与UIView之间的关系,以及layer的一些特性,然后我们会研究UIKit的UIView+block动画实现原理,为什么同样的一行代码在block里面就有动画在block外面就没动画,接下来我们将深入到layer内部,结合CABasicAnimation看看两个非常重要的概念:modelLayer和presentationLayer,以及模型和显示的同步。最后我们将通过进一步研究CABasicAnimation来研究“动画时间”这个概念。

前言

这一章中,我们将探究UIView和它持有的那个CALayer之间的关系是怎样的,并通过一个实验来证明我们的结论。这一章你将学到一些比较理论的东西,所以没有demo,更多的是文字,请放心食用。

结论

结论是最好的开胃菜

UIView是iOS开发的核心类,在我们看来,它负责几乎所有的界面展示和用户交互,这是苹果设计得非常好的一个地方——它完美的将其真正负责绘制界面的那个类封装起来了,对开发者而言,我们几乎只和UIView打交道就能完全控制一个视图的显示而不需要去管它底层究竟如何去处理的,然而我们今天必须要稍微深入进UIView中看看,以便于我们之后对动画原理的学习。

对于CALayer这个类 我相信大家都不太陌生,大多数人第一次接触这个类都是通过一个UIView对象的属性layer认识的。在学习如何给一个视图加圆角、设置边框颜色之类的效果的时候,第一次接触到了CALayer,当时并没有去理会这个东西,因为它似乎并不是UIKit框架中的东西,也不知道它有啥用,只是隐隐觉得这个家伙并不简单,事实的确如此。

实际上CALayer是属于QuartzCore框架,而这个框架是一个跨平台的绘制框架。这里的跨平台指的是在iOS和OS X系统上均能使用,也就是说CALayer能在iOS和OS X上面绘制内容(这也说明了为什么CALayer的很多属性都不是UIKit框架下面的东西,比如它的backgroundColor是CGColorRef,因为OS X中没有UIKit)。但是这两个平台接收用户交互的方式完全不一样:iOS是通过触摸事件(touch event)而OS X则是监听鼠标和键盘事件。

苹果的工程师们考虑到:这两个平台的绘制规则(如何将一个像素显示到屏幕上)都是一样的,但是交互规则完全不一样。所以他们使用了同一种绘制方式和不同的交互方式,具体的,他们将CALayer作为两个平台共同的用来绘制内容的类而针对交互方式,他们在iOS中使用了UIResponder类来响应交互在OS X中则没有UIKit里面的类取而代之是叫做NSView之类的东西。而通常情况下交互是发生在绘制内容之上的(有内容的地方才能点击),所以UIKit将CALayer封装进了UIView中,让开发者们感觉到UIView既能绘制又能处理交互,而实际上负责绘制的是UIView中的CALayer。

UIView就像电视机,CALayer则是它的屏幕,对于观众来讲我们知道电视机能显示东西、能操作(开关机、换台等)、能设置和获取各种显示属性,比如亮度、对比度等。我们对电视机的各种命令都会改变它自身的显示,就像我们修改一个UIView的背景色一样,电视机本身把如何显示的细节隐藏起来了,观众只需要简单的按个按钮(给UIView设置一个属性)就能控制它的显示了。当我们获取和设置电视机当前的亮度时,电视机只是简单的去获取和设置它的显示屏的亮度而已。我们访问和设置UIView的一些负责绘制规则的属性比如frame、center、backgroundColor等,在其持有的CALayer中都存在对应的属性,UIView只是简单的返回它自己CALayer的属性以及对自己的CALayer的这些对应的属性赋值而已。

上面说了一大堆,总结起来就一句话:UIView负责处理用户交互,负责绘制内容的则是它持有的那个CALayer,我们访问和设置UIView的这些负责显示的属性实际上访问和设置的都是这个CALayer对应的属性,UIView只是将这些操作封装起来了而已。

论证

活着就是为了证明自己

为了证实我们上面的结论,我们将通过一个具体的实验来看看UIView和它持有的这个CALayer之间是怎样进行交互的。

我们新建一个类,继承自UIView,取名为TestAnimationView。我们在这个类中重写一些方法来看看系统在我们取值和赋值的时候干了些什么。为了弄清楚UIView和其持有的那个layer之间的关系,我们需要把这个类的layer改为我们自己定义的一个layer,所以我们在这个类中声明一个私有的类TestAnimationLayer,接下来重写TestAnimationView的+layerClass方法:

+ (Class)layerClass
{
   
    return [TestAnimationLayer class];
}

这个方法将会指定这个UIVie

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值