从今天开始, 准备系统的学习一下iOS中的核心动画了, 准备花一个月时间, 利用空闲时间把所有章节内容都看完, demo都敲完, 每个章节的笔记就记在这里了, demo记在github上. 我认为的重点我会提取出来到这里记下来.
电子教程是在极客学院上的这个: http://wiki.jikexueyuan.com/project/ios-core-animation/coating-tree.html
dmeo在我的github上:
图层的树状结构
Core Animation, 顾名思义, 就是核心动画, 很容易让人误解是一个专门用来做动画的框架, 其实不然. 动画只是 Core Animation
众多功能中的冰山一角.
1. 图层和视图
在iOS中, 所有的视图都是从一个叫UIView
的基类派生而来的, UIView可以处理触摸事件, 可以支持Core Graphics绘图, 放射变换, 滑动挥着渐变的动画.
CALayer:
CALayer在概念上和UIView类似, 也可以像UIView一样, 在layer上添加或者移除subLayer, 也可以包含一些图片, 文本背景颜色等内容, 也有一些方法和属性做动画, 它和UIView最大的不同是, CALyer不能处理用户的交互.CALayer并不清楚响应者链, 所以它不能够响应事件.
UIView:
每个UIView都有一个对应的平行层级的CALayer属性,视图的职责其实是管理这个图层, 实际上, 这些背后关联的图层才是真正用来在屏幕上显示和做动画的, UIView只是对它的一个封装, 提供了一些iOS类似于出没处理的具体功能, 以及CoreAnimation底层方法的高级接口(clipsToBounds, transform等).
为什么要同时维持UIView和CALayer两个层级?
简单的说, 职责分明. Objective-C语言开发需要同时支持iOS开发和mac OS开发. 而在iOS和macOS中事件处理方式是不同的, 各种操作习惯也是不同的, iOS中是基于触摸屏幕的, Mac OS中是基于鼠标点击事件的, 所以在iOS中我们使用UIView这个视图, 而macOS中使用NSView这个视图. 而用来真正显示内容的CALayer单独列为一个新的层级, 好处就是可以在两个平台共享代码, 两个平台都使用CALayer图层, 但是上层的封装划分为UIView与NSView即可. 这样, 不管是苹果自己开发团队还是第三方其他开发团队, 都可以节约很多的时间成本.
2. 图层能用来做什么
CALayer是UIView的内部实现细节, 但是我们还是有必要去了解这个细节. 如果是简单的需求, 我们只需要使用UIView这样的高级视图即可, UIView的高级API间接的使用CALayer的相关功能, 会让开发更加简单, 但是如果想做一点改变, 做一点点与众不同的东西, 就必须借助CALayer图层了.
UIView没有暴露出来的CALayer功能:
- 阴影效果, 圆角效果, 带颜色的边框
- 3D变换
- 非矩形的范围
- 透明遮罩层
- 多级非线性动画
3. 使用图层
首先我们需要知道, CALayer被包含在 <QuartzCore/QuartzCore.h>
框架中.
默认情况下, 一个视图只有一个相关联的图层, 同时也可以支持添加无数个子图层, 如果需要添加子图层, 我们可以显式创建一个单独的图层, 并且添加到视图关联的子图层中.
使用CALayer的好处:
- 可以用来开发Macros OS和iOS挂平台的应用.
- 使用一些特殊的Layer, 有很多CALayer的子类, 用来专门处理不同的视图展示.
- 对性能特别挑剔, 或者特别注重性能的应用.
4. UIView中, 层级关系是用过Layer维系在一起的
以下代码证明: UIView中的层级关系是通过CALayer图层来关联在一起的. 就是说, 向view上面添加一个子view, 相当于在view的layer图层上添加了子view的layer图层.
// 创建一个view, 并添加到self.view上面
UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[self.view addSubview:layerView];
layerView.center = self.view.center;
layerView.backgroundColor = [UIColor lightGrayColor];
NSLog(@"%ld", layerView.layer.sublayers.count); /// result: 0
// 创建一个子view. 并将之添加到 layerView上面
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)];
[layerView addSubview:subView];
subView.backgroundColor = [UIColor redColor];
NSLog(@"%ld", layerView.layer.sublayers.count); /// result: 1
// 创建CALayer对象, 直接添加到layerView.layer图层上
CALayer *blueLayer = [CALayer layer];
[layerView.layer addSublayer:blueLayer];
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
blueLayer.frame = CGRectMake(30, 30, 30, 30);
NSLog(@"%ld", layerView.layer.sublayers.count); /// result: 2