CALayer
1.CALayer和UIView的区别
(1)UIView是UIKit的(只能iOS使用),CALayer是QuartzCore的(iOS和mac os通用)。
(2)UIView继承UIResponder,CALayer继承NSObject,UIView比CALayer多了一个事件处理的功能,也就是说,CALayer不能处理用户的触摸事件,而UIView可以。
(3)UIView来自CALayer,是CALayer的高层实现和封装,UIView的所有特性来源于CALayer支持。
(4)CABasicAnimation,CAAnimation,CAKeyframeAnimation等动画类都需要加到CALayer上。
2.CALayer
3.CALayer属性
属性 |
说明 |
是否支持隐式动画 |
anchorPoint |
和中心点position重合的一个点,称为“锚点”,锚点的描述是相对于x、y位置比例而言的默认在图像中心点(0.5,0.5)的位置 |
是 |
backgroundColor |
图层背景颜色 |
是 |
borderColor |
边框颜色 |
是 |
borderWidth |
边框宽度 |
是 |
bounds |
图层大小 |
是 |
contents |
图层显示内容,例如可以将图片作为图层内容显示 |
是 |
contentsRect |
图层显示内容的大小和位置 |
是 |
cornerRadius |
圆角半径 |
是 |
doubleSided |
图层背面是否显示,默认为YES |
否 |
frame |
图层大小和位置,不支持隐式动画,所以CALayer中很少使用frame,通常使用bounds和position代替 |
否 |
hidden |
是否隐藏 |
是 |
mask |
图层蒙版 |
是 |
maskToBounds |
子图层是否剪切图层边界,默认为NO |
是 |
opacity |
透明度 ,类似于UIView的alpha |
是 |
position |
图层位置 |
是 |
shadowColor |
阴影颜色 |
是 |
shadowOffset |
阴影偏移量 |
是 |
shadowOpacity |
阴影透明度,注意默认为0,如果设置阴影必须设置此属性 |
是 |
shadowPath |
阴影的形状 |
是 |
shadowRadius |
阴影模糊半径 |
是 |
sublayers |
子图层 |
是 |
sublayerTransform |
子图层形变 |
是 |
transform |
图层形变 |
是 |
4.CALayer层的属性:position(位置) 和 anchorPoint (锚点)
(1)简单介绍
CALayer有2个非常重要的属性:position 和 anchorPoint
@property CGPoint position;
用来设置CALayer在父层中的位置
以父层的左上角为原点(0, 0)
@property CGPoint anchorPoint;
称为“定位点”、“锚点”
决定着`CALayer上的哪个点`会与`position属性表示的点`重合
anchorPoint的坐标轴以CALayer的左上角为原点(0, 0),它的x、y取值范围都是0~1,默认值为(0.5, 0.5)
(2)图示
anchorPoint
它的取值为0~1
红色图层的anchorPoint为(0,0)
红色图层的anchorPoint为(0.5,0.5)
红色图层的anchorPoint为(1,1)
红色图层的anchorPoint为(0.5,0)
position和anchorPoint
添加一个红色图层到绿色图层上,红色图层显示到什么位置,由position属性决定
假设红色图层的position是(100,100)
到底把红色图层的哪个点移动到(100,100)的坐标位置,由锚点确定的。
红色图层的锚点是(0,0)
红色图层的锚点是(0.5,0.5)
红色图层的锚点是(1,1)
红色图层的锚点是(0.5,0)
(3)代码
- (void)positionAndAnchorPoint { CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.backgroundColor = [UIColor redColor].CGColor; //位置 layer.position = CGPointMake(100, 100); //锚点(0<= x,y <= 1.0) layer.anchorPoint = CGPointMake(0.5, 0.5); [self.view.layer addSublayer:layer]; }
5.图层内容和内容模式
内容:默认为空,一般为CGImageRef类型
@property(nullable, strong) id contents;
/* An object providing the contents of the layer, typically a CGImageRef,
* but may be something else. (For example, NSImage objects are
* supported on Mac OS X 10.6 and later.) Default value is nil.
* Animatable. */
内容模式:图片会压缩变形,需要设置内容的模式
@property(copy) NSString *contentsGravity;
/* A string defining how the contents of the layer is mapped into its
* bounds rect. Options are `center', `top', `bottom', `left',
* `right', `topLeft', `topRight', `bottomLeft', `bottomRight',
* `resize', `resizeAspect', `resizeAspectFill'. The default value is
* `resize'. Note that "bottom" always means "Minimum Y" and "top"
* always means "Maximum Y". */
/** Layer `contentsGravity' values.
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
kCAGravityResize
kCAGravityResizeAspect
kCAGravityResizeAspectFill
**/
- (void)contentAndContentMode { CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.backgroundColor = [UIColor lightGrayColor].CGColor; //位置 layer.position = CGPointMake(100, 100); NSLog(@"%@",NSStringFromCGRect(layer.frame)); //设置内容 layer.contents = (id)[UIImage imageNamed:@"c75c10385343fbf2c6e17e6eb27eca8064388faa"].CGImage; //图片会压缩变形,需要设置内容的模式 //内容的模式,和UIImageView里面的contentMode相似 layer.contentsGravity = kCAGravityResizeAspect; [self.view.layer addSublayer:layer]; }
6.图片添加阴影 和 阴影路径(CGMutablePathRef)
添加阴影
注意:layer.shadowOpacity 默认值为 0 ,即阴影默认是透明的。设置为 1 才显示引用。
- (void)shadow { CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.backgroundColor = [UIColor lightGrayColor].CGColor; //位置 layer.position = CGPointMake(100, 100); //阴影颜色 layer.shadowColor = [UIColor redColor].CGColor; //阴影半径 layer.shadowRadius = 2; //阴影偏移 layer.shadowOffset = CGSizeMake(30, 30); //阴影是否是不透明,1表示不透明(默认是0) layer.shadowOpacity = 1.0; [self.view.layer addSublayer:layer]; //创建阴影的路径 CGMutablePathRef path = CGPathCreateMutable(); #if 0 //添加圆弧路径 CGPathAddArc(path, NULL, 50, 50, 100, 0, M_PI * 2, YES); #endif //添加方形路径 CGPathAddRect(path, NULL, CGRectMake(0, 0, 200, 200)); //设置阴影路径 layer.shadowPath = path; }
7.剪切超过父图层的部分
- (void)clip { CALayer *l1 = [CALayer layer]; l1.bounds = CGRectMake(0, 0, 100, 100); l1.backgroundColor = [UIColor lightGrayColor].CGColor; l1.position = CGPointMake(100, 100); [self.view.layer addSublayer:l1]; //剪切超过父图层的部分 l1.masksToBounds = YES; CALayer *l2 = [CALayer layer]; l2.bounds = CGRectMake(0, 0, 100, 100); //位置 l2.position = CGPointMake(100, 100); l2.backgroundColor = [UIColor purpleColor].CGColor; [l1 addSublayer:l2]; }
8.图片添加边框和圆角
边框宽度默认为0,设置完颜色要记得设置宽度
- (void)border { CALayer *l = [CALayer layer]; l.bounds = CGRectMake(0, 0, 100, 100); l.backgroundColor = [UIColor lightGrayColor].CGColor; l.position = CGPointMake(100, 100); //边框颜色 l.borderColor = [UIColor redColor].CGColor;; //边框宽度 l.borderWidth = 3; //圆角半径 l.cornerRadius = 20; [self.view.layer addSublayer:l]; }
9.剪切图片的一部分
通过设置 layer.contentsRect 来截取出图片的一部分
contentsRect:
/* A rectangle in normalized image coordinates defining the subrectangle of the `contents' property that will be drawn into the layer.
* If pixels outside the unit rectangles are requested, the edge pixels of the contents image will be extended outwards.
* If an empty rectangle is provided, the results are undefined.
* Defaults to the unit rectangle [0 0 1 1]. Animatable. */
- (void)clipSome { CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(100, 100, 200, 200); layer.contents = (id)[UIImage imageNamed:@"20101116120457-1388528443"].CGImage; [self.view.layer addSublayer:layer]; //把一个图片切成多块 for (int i = 0; i < 9; i++) { CALayer *l = [CALayer layer]; l.frame = CGRectMake(50 + 90*(i%3), 350 + 90*(i/3), 80, 80); l.contents = (id)[UIImage imageNamed:@"20101116120457-1388528443"].CGImage; //设置内容的大小 l.contentsRect = CGRectMake(1.0/3.0*(i%3), 1.0/3.0*(i/3), 1.0/3.0, 1.0/3.0); l.backgroundColor = [UIColor redColor].CGColor; [self.view.layer addSublayer:l]; } }
10.仿射变换
layer中的仿射变换与label中的类似:
UILabel *l; 对应 layer
l.transform ----> CGAffineTransform
l.affineTransform ----> CGAffineTransform;
l.transform ----> CATransform3D
- (void)affineTransform { CALayer *l = [CALayer layer]; l.bounds = CGRectMake(0, 0, 100, 100); l.backgroundColor = [UIColor lightGrayColor].CGColor; //位置 l.position = CGPointMake(100, 100); l.contents = (id)[UIImage imageNamed:@"c75c10385343fbf2c6e17e6eb27eca8064388faa"].CGImage; [self.view.layer addSublayer:l]; #if 0 // ------ 仿射变换 ------ //旋转45度 l.affineTransform = CGAffineTransformMakeRotation(M_PI/6); //比例变换 CGAffineTransformMakeScale(<#CGFloat sx#>, <#CGFloat sy#>); //偏移 CGAffineTransformMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>) #endif #if 0 // ------ 3D变换 ------ //旋转 //注意:旋转90读时图片与人视线平行 --> 看不见图片 l.transform = CATransform3DMakeRotation(M_PI/4, 1, 1, 1); //比例 CATransform3DMakeScale(<#CGFloat sx#>, <#CGFloat sy#>, <#CGFloat sz#>); //偏移 CATransform3DMakeTranslation(<#CGFloat tx#>, <#CGFloat ty#>, <#CGFloat tz#>) //m34 = -1/xxxx //CATransform3DMakeRotation 类中 m34为人的视角,有兴趣可以研究一下 #endif }
11.CAShapeLayer和UIBezierPath(贝塞尔曲线)
CAShapeLayer
CAShapeLayer是CALayer的子类,是Quare 2D中对图层操作最基本的一个扩展。通过它,我们可以绘制各种图形,特别是不规则图形。
每个CAShapeLayer对象都代表着将要被渲染到屏幕上的形状(shape)。具体的形状由其path(类型为CGPathRef)属性指定,形状可以是任意的,比如星形、菱形等等。
普通的CALayer在初始化时需要指定frame值,它本身是有形状,而且是矩形。CAShapeLayer初始化时也需要指定frame值,但它本身没有形状,它的形状来源于其属性path。
UIBezierPath
UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲线段去创建。我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。
12.环形进度条实现
13.圆形头像视图
posted on 2016-03-13 19:41 Wilson_CYS 阅读(330) 评论(0) 编辑 收藏 举报