一、自定义层的方法1

方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图

1.创建一个CALayer的子类

2.在.m文件中覆盖drawInContext:方法,在里面绘图

 1 @implementation MJLayer
2
3 #pragma mark 绘制一个实心三角形
4 - (void)drawInContext:(CGContextRef)ctx {
5 // 设置为蓝色
6 CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
7
8
9 // 设置起点
10 CGContextMoveToPoint(ctx, 50, 0);
11 // 从(50, 0)连线到(0, 100)
12 CGContextAddLineToPoint(ctx, 0, 100);
13 // 从(0, 100)连线到(100, 100)
14 CGContextAddLineToPoint(ctx, 100, 100);
15 // 合并路径,连接起点和终点
16 CGContextClosePath(ctx);
17
18 // 绘制路径
19 CGContextFillPath(ctx);
20 }
21
22 @end

3.在控制器中添加图层到屏幕上

1 MJLayer *layer = [MJLayer layer];
2 // 设置层的宽高
3 layer.bounds = CGRectMake(0, 0, 100, 100);
4 // 设置层的位置
5 layer.position = CGPointMake(100, 100);
6 // 开始绘制图层
7 [layer setNeedsDisplay];
8 [self.view.layer addSublayer:layer];

注意第7行,需要调用setNeedsDisplay这个方法,才会触发drawInContext:方法的调用,然后进行绘图

二、自定义层的方法2

方法描述:设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法,当CALayer需要绘图时,会调用delegate的drawLayer:inContext:方法进行绘图。

* 这里要注意的是:不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题。UIView和它内部CALayer的默认关系图:

1.创建新的层,设置delegate,然后添加到控制器的view的layer中

 1 CALayer *layer = [CALayer layer];
2 // 设置delegate
3 layer.delegate = self;
4 // 设置层的宽高
5 layer.bounds = CGRectMake(0, 0, 100, 100);
6 // 设置层的位置
7 layer.position = CGPointMake(100, 100);
8 // 开始绘制图层
9 [layer setNeedsDisplay];
10 [self.view.layer addSublayer:layer];

* 在第3行设置了CALayer的delegate,这里的self是指控制器

* 注意第9行,需要调用setNeedsDisplay这个方法,才会通知delegate进行绘图

2.让CALayer的delegate(前面设置的是控制器)实现drawLayer:inContext:方法

 1 #pragma mark 画一个矩形框
2 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
3 // 设置蓝色
4 CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
5 // 设置边框宽度
6 CGContextSetLineWidth(ctx, 10);
7
8 // 添加一个跟层一样大的矩形到路径中
9 CGContextAddRect(ctx, layer.bounds);
10
11 // 绘制路径
12 CGContextStrokePath(ctx);
13 }

三、其他

1.总结

无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。

2.UIView的详细显示过程

* 当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

* 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

CALayer4-自定义层的更多相关文章

  1. Keras处理已保存模型中的自定义层(或其他自定义对象)

    如果要加载的模型包含自定义层或其他自定义类或函数,则可以通过 custom_objects 参数将它们传递给加载机制: from keras.models import load_model # 假设 ...

  2. MXNET:深度学习计算-自定义层

    虽然 Gluon 提供了大量常用的层,但有时候我们依然希望自定义层.本节将介绍如何使用 NDArray 来自定义一个 Gluon 的层,从而以后可以被重复调用. 不含模型参数的自定义层 我们先介绍如何 ...

  3. 『MXNet』第四弹_Gluon自定义层

    一.不含参数层 通过继承Block自定义了一个将输入减掉均值的层:CenteredLayer类,并将层的计算放在forward函数里, from mxnet import nd, gluon from ...

  4. Keras 自定义层

    1.对于简单的定制操作,可以通过使用layers.core.Lambda层来完成.该方法的适用情况:仅对流经该层的数据做个变换,而这个变换本身没有需要学习的参数. # 切片后再分别进行embeddin ...

  5. 从头学pytorch(十一):自定义层

    自定义layer https://www.cnblogs.com/sdu20112013/p/12132786.html一文里说了怎么写自定义的模型.本篇说怎么自定义层. 分两种: 不含模型参数的la ...

  6. keras中保存自定义层和loss

    在keras中保存模型有几种方式: (1):使用callbacks,可以保存训练中任意的模型,或选择最好的模型 logdir = './callbacks' if not os.path.exists ...

  7. tf更新tensor/自定义层

    修改Tensor特定位置的值 如 stack overflow 中提到的方案. TensorFlow不让你直接单独改指定位置的值,但是留了个歪门儿,就是tf.scatter_update这个方法,它可 ...

  8. 自定义层or网络

    目录 Outline keras.Sequential Layer/Model MyDense MyModel Outline keras.Sequential keras.layers.Layer ...

  9. 在Caffe中使用 DIGITS(Deep Learning GPU Training System)自定义Python层

    注意:包含Python层的网络只支持单个GPU训练!!!!! Caffe 使得我们有了使用Python自定义层的能力,而不是通常的C++/CUDA.这是一个非常有用的特性,但它的文档记录不足,难以正确 ...

  10. 『开发技巧』Keras自定义对象(层、评价函数与损失)

    1.自定义层 对于简单.无状态的自定义操作,你也许可以通过 layers.core.Lambda 层来实现.但是对于那些包含了可训练权重的自定义层,你应该自己实现这种层. 这是一个 Keras2.0  ...

随机推荐

  1. ThinkPHP开发笔记-用户登录注册

    1.修改模块配置,Application/当前模块名/Conf/config.php <?php return array( //数据库配置信息 'DB_TYPE' => 'mysql', ...

  2. background-size css background-images

    在设计网页时,经常会用到背景图片来达到视觉效果. 一般情况下用repeat的方式是最适全不过了,不过有时间是采用整图来充当背景,那么这个时候就会有多种可能性的存在了. 整图来做背景一般是采用no-re ...

  3. 前端构建大法 Gulp 系列

    参考: 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp ...

  4. 堆 Heap

    2018-03-01 20:38:34 堆(Heap)是可以用来实现优先的队列的数据结构,而不是堆栈. 若采用数组或者链表实现优先队列 若采用树的结构 如果采用二叉搜索树,那么每次删除,比如删除最大值 ...

  5. 1012: [JSOI2008]最大数maxnumber 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=1012 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数 ...

  6. sqlserver数据库标注为可疑的解决办法

    前几天客户那边的服务器死机了,然后客户强制关机,重新启动服务器后,系统就没法正常使用,连接不上服务器,我远程操作后,看到数据库标注为可疑,由于客户之前没备份数据库,看来只能是修复了: 1:停止数据库服 ...

  7. IOS-CocoaPods制作篇

    作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/20067595 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关 ...

  8. wxpython的简单的应用

    import wximport wx.xrc import pandas as pd from conf.env import * # 允许选择的文件wildcard = "Python s ...

  9. 【后台测试】postman简介

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/6266047.html 在接口测试的过程中,经常拿到一个接口 ...

  10. is null 和=null的区别

    数据库中 null 表示 不可知,不确定 所以 判断都用 字段 is null的方式进行判断 而 = null .<> null 的判断结果,仍然是不可知,不确定,所以 不会返回任何结果. ...