500-CALayer
一、CALayer的常用设置
1.UIView的图层
1 UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2.0 - 50, 30, 100, 100)]; 2 redView.backgroundColor = [UIColor redColor]; 3 [self.view addSubview:redView]; 4 5 // 1.边框宽度和边框颜色 6 redView.layer.borderWidth = 5; 7 redView.layer.borderColor = [UIColor purpleColor].CGColor; 8 9 // 2.图层实现设置圆角 10 // 对于UIView的圆角设置我们可以不需要设置masksToBounds为YES 11 redView.layer.cornerRadius = 30; 12 13 // 3.图层实现设置阴影 14 // 阴影的设置必须设置masksToBounds为YES 15 redView.layer.shadowColor = [UIColor yellowColor].CGColor; // 阴影颜色 16 redView.layer.shadowOffset = CGSizeMake(20, 20); // 阴影偏差(右下偏正左上偏负) 17 redView.layer.shadowOpacity = 0.5; // 图层阴影的透明度(默认为0) 18 19 // 4.图层的裁剪(默认为NO,超出图层的部分就会被裁剪) 20 redView.layer.masksToBounds = NO;
2.UIImageView的图层
1 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2.0 - 50, 160, 100, 100)]; 2 imageView.image = [UIImage imageNamed:@"1.jpg"]; 3 [self.view addSubview:imageView]; 4 5 // 1.设置圆角 6 imageView.layer.cornerRadius = 10; 7 8 // 2.在设置图片圆角时,必须设置为裁剪效果 9 imageView.layer.masksToBounds = YES;
总结:UIView和UIImageView圆角设置的区别
对于UIImageView而言,CALayer有主层和子层之分,主层上会依照图层参数设置展示,但是Image是显示在子层上的,所以在设置圆角时,必须设置图层剪裁效果(裁剪超出主层的部分)
对于UIView而言,CALayer只有一个主层,所以在设置圆角时可以不用设置剪裁效果
二、图层的三维属性
1.方法设置
1 // 创建UIImageView 2 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2.0 - 50, 100, 100, 100)]; 3 imageView.image = [UIImage imageNamed:@"1.jpg"]; 4 [self.view addSubview:imageView]; 5 6 // 1.三维缩放 7 // x:宽度缩放比例 8 // y:高度缩放比例 9 // z:由于iOS7的扁平化无效 10 imageView.layer.transform = CATransform3DMakeScale(1.5, 1.5, 0); 11 12 // 2.三维平移 13 // x:x方向平移(正右负左) 14 // y:y方向平移(正下负上) 15 // z:由于iOS7的扁平化无效 16 imageView.layer.transform = CATransform3DMakeTranslation(10, 10, 0); 17 18 // 3.三维旋转 19 // 旋转轴:{(0, 0, 0), (x, y, z)} 20 // 旋转方向:逆时针旋转 21 // 旋转弧度:angle 22 imageView.layer.transform = CATransform3DMakeRotation(M_PI_4, 1, 1, 0);
2.KVC赋值
1)给结构体赋值
1 // 创建UIImageView 2 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2.0 - 50, 100, 100, 100)]; 3 imageView.image = [UIImage imageNamed:@"1.jpg"]; 4 [self.view addSubview:imageView]; 5 // 1.图片三维平面旋转 6 // transform:结构体,传值必须是包装为NSValue 7 NSValue *value1 = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 1, 0)]; 8 [imageView.layer setValue:value1 forKeyPath:@"transform"]; 9 10 // 2.图片二维平面平移 11 // transform.translation:结构体,传值必须是包装为NSValue 12 NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(100, 20)]; 13 [imageView.layer setValue:value2 forKeyPath:@"transform.translation"];
2)给结构体中的成员赋值
1 // 创建UIImageView 2 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width / 2.0 - 50, 100, 100, 100)]; 3 imageView.image = [UIImage imageNamed:@"1.jpg"]; 4 [self.view addSubview:imageView]; 5 // 1.图片宽度缩小为0.5 6 [imageView.layer setValue:@(0.5) forKeyPath:@"transform.scale.x"]; 7 8 // 2.图片二维平面旋转45° 9 [imageView.layer setValue:@(M_PI_4) forKeyPath:@"transform.rotation"]; 10 11 // 3.图片二维平面平移(x轴向右移动100) 12 [imageView.layer setValue:@100 forKeyPath:@"transform.translation.x"];
总结:苹果官方文档中搜索“CATransform3D key paths”,这里面关于KVC赋值的一些Key对应的Value类型写得很清楚
直接上图:


三、CALayer的创建和自定义
1.CALayer的创建
代码演示之前我们必须搞清楚,CALayer的两个重要属性(position和anchorPoint)
1)position:CALayer相对于父层中原点(0, 0)的位置
2)anchorPoint:定位点、锚点 -- 以自己的左上角为原点(0, 0)

其实就一句话:锚点决定着CALayer自身的哪一个点(默认为中点(0.5, 0.5))在父层中的位置坐标是position的坐标值
1 // 1.初始化CALayer对象 2 // CALayer *redLayer = [[CALayer alloc] init]; 3 CALayer *redLayer = [CALayer layer]; 4 5 // 2.设置CALayer的位置和尺寸 6 // redLayer的(1, 0.5)这个点在父层中的坐标是(50, 50) 7 // 设置锚点(默认(0.5, 0.5)) 8 redLayer.anchorPoint = CGPointMake(1, 0.5); 9 redLayer.bounds = CGRectMake(0, 0, 100, 100); 10 redLayer.position = CGPointMake(50, 50); 11 // redLayer.frame = CGRectMake(50, 50, 100, 100); 12 13 // 3.设置背景色(注意是CG类型) 14 redLayer.backgroundColor = [UIColor redColor].CGColor; 15 16 // 4.设置边框 17 redLayer.borderWidth = 10; 18 redLayer.borderColor = [UIColor greenColor].CGColor; 19 20 // 5.设置圆角 21 redLayer.cornerRadius = 10; 22 23 // 6.设置阴影 24 redLayer.shadowColor = [UIColor yellowColor].CGColor; 25 redLayer.shadowOffset = CGSizeMake(20, 20); 26 redLayer.shadowOpacity = 0.5; // 设置阴影必须设置,默认为0 27 28 // 7.设置头CALayer透明度 29 redLayer.opacity = 0.5; 30 31 // 8.将新建的CALayer对象加载在self.view.layer上 32 [self.view.layer addSublayer:redLayer];
2.CALayer实现UIImageView的效果
1 // 1.初始化CALayer对象 2 CALayer *redLayer = [CALayer layer]; 3 4 // 2.设置CALayer的位置和尺寸 5 redLayer.bounds = CGRectMake(0, 0, 100, 100); 6 redLayer.position = CGPointMake(100, 100); 7 8 // 3.设置背景色(注意是CG类型) 9 redLayer.backgroundColor = [UIColor redColor].CGColor; 10 11 // 4.设置边框 12 redLayer.borderWidth = 10; 13 redLayer.borderColor = [UIColor greenColor].CGColor; 14 15 // 5.设置圆角 16 redLayer.cornerRadius = 10; 17 18 // 6.设置CALayer的内容(id类型) 19 // [UIImage imageNamed:@"1.jpg"].CGImag (C语言类型) 20 redLayer.contents = (id)[UIImage imageNamed:@"1.jpg"].CGImage; 21 22 // 7.CALayer的内容会在子层显示,如设置圆角就必须设置剪裁效果 23 redLayer.masksToBounds = YES; 24 25 // 8.加载 26 [self.view.layer addSublayer:redLayer];
总结:既然CALayer也能实现UIImageView的效果,那么对于UIView和CALayer就有了一个选择的问题
1)对比CALayer,UIView多了一个事件处理的功能;也就是说,CALayer是不能处理用户的触摸事件
2)所以,如果要求显示出来的东西需要用户交互,必选UIView;如不需要,二者均可
3)另外,由于CALayer不需要处理事件,所以其性能也就相应会高一些,更加轻量级
3.自定义图层
1)继承的方法自定义图层
1 // CustomLayer.h文件 2 #import <QuartzCore/QuartzCore.h> 3 4 @interface CustomLayer : CALayer 5 6 @end 7 8 // CustomLayer.m文件 9 #import "CustomLayer.h" 10 11 @implementation CustomLayer 12 13 #pragma mark - 自定义CALayer调用setNeedsDisplay方法后会调用 14 - (void)drawInContext:(CGContextRef)ctx 15 { 16 // 设置填充颜色 17 CGContextSetRGBFillColor(ctx, 1, 0, 0, 1); 18 // 内接圆 19 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100)); 20 // 渲染 21 CGContextFillPath(ctx); 22 } 23 24 @end 25 26 // ViewController.m文件 27 #import "ViewController.h" 28 #import "CustomLayer.h" // 导入自定义CALayer头文件 29 30 @implementation ViewController 31 32 - (void)viewDidLoad 33 { 34 [super viewDidLoad]; 35 36 CustomLayer *customLayer = [[CustomLayer alloc] init]; 37 customLayer.anchorPoint = CGPointMake(0, 0); 38 customLayer.position = CGPointMake(10, 40); 39 customLayer.bounds = CGRectMake(0, 0, 120, 120); 40 customLayer.backgroundColor = [UIColor purpleColor].CGColor; 41 // 一定要调用重绘 42 [customLayer setNeedsDisplay]; 43 [self.view.layer addSublayer:customLayer]; 44 } 45 46 @end
2)代理的方法自定义图层
1 // ViewController.m文件 2 #import "ViewController.h" 3 4 @implementation ViewController 5 6 - (void)viewDidLoad 7 { 8 [super viewDidLoad]; 9 10 CALayer *customLayer = [[CALayer alloc] init]; 11 customLayer.anchorPoint = CGPointMake(0, 0); 12 customLayer.position = CGPointMake(10, 200); 13 customLayer.bounds = CGRectMake(0, 0, 120, 120); 14 customLayer.backgroundColor = [UIColor yellowColor].CGColor; 15 // 该代理不用遵守任何协议,该代理方法为NSObject的方法 16 customLayer.delegate = self; 17 // 一定要调用重绘 18 [customLayer setNeedsDisplay]; 19 [self.view.layer addSublayer:customLayer]; 20 } 21 22 #pragma mark - 代理方法<NSObject的方法> 23 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx 24 { 25 // 设置填充颜色 26 CGContextSetRGBFillColor(ctx, 1, 0, 0, 1); 27 // 内接圆 28 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100)); 29 // 渲染 30 CGContextFillPath(ctx); 31 } 32 33 @end
四、CALayer的隐式动画
1.概念
每一个UIView内部都默认关联着一个CALayer,我们称这个Layer为Root Layer(根层)
所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画。当我们对这些非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果
2.代码实例
1 // ViewController.m文件 2 #import "ViewController.h" 3 4 @interface ViewController () 5 6 @property (nonatomic, strong) CALayer *blueLayer; 7 8 @end 9 10 @implementation ViewController 11 12 - (void)viewDidLoad 13 { 14 [super viewDidLoad]; 15 16 _blueLayer = [CALayer layer]; 17 // 设置锚点 18 _blueLayer.anchorPoint = CGPointMake(0, 0); 19 _blueLayer.position = CGPointMake(100, 100); 20 _blueLayer.bounds = CGRectMake(0, 0, 100, 100); 21 _blueLayer.backgroundColor = [UIColor blueColor].CGColor; 22 [self.view.layer addSublayer:_blueLayer]; 23 } 24 25 #pragma mark - 点击改变一些属性 26 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 27 { 28 // 改变_blueLayer的位置 29 if (_blueLayer.position.y <= self.view.bounds.size.height - 100) { 30 _blueLayer.position = CGPointMake(_blueLayer.position.x, _blueLayer.position.y + 50); 31 } else if (_blueLayer.position.y > self.view.bounds.size.height - 100) { 32 _blueLayer.position = CGPointMake(_blueLayer.position.x, 100); 33 } 34 } 35 36 @end
关闭隐式动画:
1 // 开启事物 2 [CATransaction begin]; 3 // 开闭隐式动画效果(设置为YES) 4 [CATransaction setDisableActions:YES]; 5 6 // 改变_blueLayer的位置 7 if (_blueLayer.position.y <= self.view.bounds.size.height - 100) { 8 _blueLayer.position = CGPointMake(_blueLayer.position.x, _blueLayer.position.y + 50); 9 } else if (_blueLayer.position.y > self.view.bounds.size.height - 100) { 10 _blueLayer.position = CGPointMake(_blueLayer.position.x, 100); 11 } 12 13 // 提交事物 14 [CATransaction commit];
3.如何查看CALayer的哪些属性有隐性动画效果
苹果官方文档搜索“CALayer Animatable Properties”,直接上图


浙公网安备 33010602011771号