一、引出问题
在开始分析原理之前,我们先来看一个问题:
我们都知道 UIView
与 CALayer
之间的关系,通俗的来说,UIView
内部封装了一个 CALayer
, 其中 CALayer
负责展示UI,而 UIView
负责处理交互事件。
其中 UIView
的所有UI信息都会对应到 CALayer
上,即改变 UIView
的位置信息与改变 CALayer
的位置信息效果是一样的。
由上述结论,如果我们只是展示UI而无需交互,那么可以使用 CALayer
来替代 UIView
,从而避免多余的内存占用。
既然如此,下面代码说展示的三个视图表现应当是一致的:
@interface ViewController ()
@property (nonatomic, strong) UIView *redView;
@property (nonatomic, strong) UIView *greenView;
@property (nonatomic, strong) CALayer *yellowLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.redView removeFromSuperview];
self.redView = nil;
[self.greenView removeFromSuperview];
self.greenView = nil;
[self.yellowLayer removeFromSuperlayer];
self.yellowLayer = nil;
self.redView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 50, 50)];
self.redView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.redView];
self.greenView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, 50, 50)];
self.greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.greenView];
self.yellowLayer = [[CALayer alloc] init];
self.yellowLayer.frame = CGRectMake(0, 300, 50, 50);
self.yellowLayer.backgroundColor = [UIColor yellowColor].CGColor;
[self.view.layer addSublayer:self.yellowLayer];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.redView.frame = CGRectMake(200, 100, 50, 50);
self.greenView.layer.frame = CGRectMake(200, 200, 50, 50);
self.yellowLayer.frame = CGRectMake(200, 300, 50, 50);
});
}
@end
但真实情况确实如下图所示:
对 UIView
和 UIView
的 layer 设置 frame,视图会直接显示在对应位置,但对 CALayer
设置 frame,则会有一个移动的动画,这是怎么回事呢?
如果百度一下,所有答案都会是 隐式动画
,但隐式动画是个什么,为 CALayer
设置 frame 为什么会有隐式动画,为什么为 UIView
的 layer 设置 frame 却没有触发隐式动画呢?
这些问题将会在我们分析动画原理的过程中得到解答。
二、CALayer展示原理
既然上述代码表现出不同的UI,那么我们就从展示UI的 CALayer
出发来找寻答案。
CALayer
有许多属性,其中有两个只读属性较为特殊:
- (nullable instancetype)presentationLayer;
- (instancetype)modelLayer;
这两个属性分别对应的是 CALayer
的展示层和模型层,这两个属性的用处及关系如下:
- CALayer的modelLayer默认为CALayer本身,modelLayer的作用为存储CALayer真实的UI信息,而不显示在屏幕上,所以称modelLayer为模型层;
- presentationLayer的作用为在屏幕每次刷新时(iPhone频率为60次/秒),从modelLayer中获取最新的UI信息,然后进行渲染展示在屏幕上,所以称presentationLayer为显示层;
- presentationLayer在屏幕刷新时,若CALayer层有CAAnimation存在,那么presentationLayer会忽略modelLayer中存储的UI信息,直接从CAAnimation中计算出对应UI信息,然后进行渲染展示。
由以上 C