图层
- UIView之所以能显示到界面上是因为有一个图层。(CALayer)
一、CALayer的基本使用
通过CALayer对象, 可以很方便的调整UIView的一些外观属性。
设置边框(在IOS6中必须导入Quarz框架, 才能设置颜色、粗细):borderWith\borderColor
设置圆角:cornerRadius = 10;
设置阴影: shadowColor = [UIColor blackColor].CGColor;
设置阴影偏差: shadowOffSet = CGSizeMake(10, 10); // 向左向右偏移10
设置阴影透明度: shadowOpacity = 0.5; (masksToBounds相当于clipToBounds, 会将超出边框的剪切掉)
主层与子层
控件的Layer不一定只有一个, 位于根节点的层称为主层。其它称为子层。当你设置ImageView的layer的圆角属性缺看不到, 那是因为子层盖住了主层,所以我们看不到已经变为圆角的主层。这时可以设置masksToBounds来将超出主层的部分裁剪掉。
二、图层的transform(图层的transform是3D的, CA ==》 CoreAnimation)
1.结构体方式:
绕着xy平面的对角线选择。self.iconView.layer.transform = CATransform3DMakeRotaion(M_PI_4, 1, 1, 0);
2.KVC方式
objc
// CATransformXX创建出来的是结构体 NSValue * value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 0, 0, 1)]; [self.iconView.layer setValue:value forKeyPath: @"transform"];
如果仅仅只是想做二维平面的旋转
objc
[self.iconView.layer setValue:@(M_PI_2) forKeyPath: @"transform.rotation"]
如果仅仅是y方向的缩放
objc
[self.iconView.layer setValue:@(M_PI_2) forKeyPath: @"transform.scale.y"]
查阅官方文档: CATransform3D key path(translation、scale、rotation)
三、新建图层(两种方式)
objc
// alloc方式、layer方式 CALayer * layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.bounds = CGRectMake(0, 0 , 100, 100); layer.position = CGPointMake(200, 100); // 设置图层的内容 // 设置layer的属性, 右边一定是结构体类型。所以要CG // 之所以强制是因为contents id类型 layer.maskToBounds = YES; layer.contents = (id)[UIImage imageNamed: @"lufy"].CGImage; // 添加为layer的子图层 [self.view.layer addSublayer: layer];
UIView和CALayer的选择
UIView比CALayer多的是处理事件的功能。UIView之所以能显示出东西, 是因为其里面有一个CALayer图层。
所以如果要根用户交互用UIView.如果不需要交互,CALayer性能会更高。
CALayer的疑惑
1.首先
CALayer是定义在QuartzCore
CGImageRef\ CGColorRef两种数据类型定义在CoreGraphics框架中
UIColor、UIImage定义在UIKit框架
2.其次
QuartzCore框架和CoreGraphics框架是一个瓜平台。在IOS和OSX上都能用
但UIKit只能在IOS中使用(类都以UI开头.)
为了保证可一直性, QuarzCoreb不能使用UIImage、UIColor只能使用CGImageRef、CGColorRef。
这样就能保持根UIKit没有任何关系。
四、position和anchorPoint
position:
用来设置CALayer在父层中的位置
以父层的左上角为原点(0, 0)
anchorPoint(锚点)
决定着CALayer上哪个点会在position属性所指的位置。
以自己的左上角为左边原点。
一般常用的5个锚点, 左上角(0, 0)、左下角(0, 1)、右上角(1, 0)、右下角(1, 1)、中心点(0.5, 0.5)。
五、隐式动画(练习)
当对非Root-Layer部分属性进行修改。就会产生一些动画效果。(一该属性就会动画)
这些属性称为Animatable Properties(可动画属性)
几个常见的Animatable Properties:
bounds: 用于设置CALayer的宽高。修改这个属性会产生缩放动画
backgroundColor: 设置CALayer的背景色。修改这个属性会产生背景色渐变的动画
position: 产生平移动画。
头文件中有Animtable都是可以做隐式动画的属性。或者在Dash中输入CALayer查看文档。
六、自定义图层(本质就是在图层上绘图)
方式一
继承自CALayer
重写drawInContext:(CGContextRef)ctx; // ctx是图层上下文
调用setNeedsDisplay, 图层才会调用drawInContext进行绘制。
方式二:(交给代理做)
为什layer的代理没有协议。因为这个方法是NSObject方法, 所以就不用说明协议。
设置layer的代理对象
实现drawLayer:inContext:方法
总结:
本节需要掌握
- CALayer的基本属性
- CALayer与View的关系(简单关系, View能显示的原因)
- position和anchorPoint的作用(anchorPoint)
UIView与CALayer的关系深入理解
控件的图层的代理其实就是控件本身。所以我们实现drawRect才能实现绘制UIView。需要注意的是不能更改View内部的代理。
UIView详细的显示过程(面试)
- view.layer会准备一个Layer Graphics Context(图形上下文)并传给view.layer.delegate的drawLayer:inContext.
所以View其实只是图层的代理, 当图层需要显示的时候。会调用drawLayer:inContext:方法。
而这个方法中, 如果代理存在, 又会调用delegate的drawRect:(CGRect)rect方法来绘制到图层上。
- 所以View上的drawRect所画的东西都会绘制到view.layer上面
- 系统再将view.layer内容拷贝到屏幕, 完成view的显示。