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”,直接上图

 

posted @ 2016-03-16 14:06  Frank9098  阅读(125)  评论(0)    收藏  举报