CALayer寄宿图

作者: MonKey_Money | 来源:发表于2020-07-26 18:37 被阅读0次

寄宿图

CALayer 类能够包含一张图片,这个图片就是CALayer寄宿图,用属性contents进行赋值。

contents属性

contents为CALayer的属性,这个属性的类型为id,如果你天真的认为id为任意类型你就被骗了,当你直接赋值给这个属性一个UIImage对象时,它是不会显示这个图片的。
Mac OS下CGImage和NSImage类型都起作用。
iOS下,如果把CGImageRef类型赋值给contents,那你将会得到一个编译错误,因为CGImageRef并不是一个真正的 Cocoa对象,而是一个Core Foundation类型。所以我们需要转换。

layer.contents = (__bridge id)image.CGImage;

示例代码

   CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(20, 20, 100, 100);
    layer.contents = (__bridge id)[UIImage imageNamed:@"huhu.jpg"].CGImage;
    [self.view.layer addSublayer:layer];
image.png

contentGravity

content内容大小和CALayer的frame并不是都是一致的,为了适应CALayer的尺寸,layer提供了contentGravity属性,在UIView和CALayer的contentGravity对应的属性是contentMode.
-kCAGravityCenter //图片大小不做改变,图片中心在layer的中心
-kCAGravityTop //图片大小不做改变,图片和layer下面对齐
-kCAGravityBottom //图片大小不做改变,图片和layer上面对齐
-kCAGravityLeft //图片大小不做改变,图片和layer左边对齐
-kCAGravityRight //图片大小不做改变,图片和layer右边对齐
-kCAGravityTopLeft //图片大小不做改变,图片和layer左下边对齐
-kCAGravityTopRight //图片大小不做改变,图片和layer右下边对齐
-kCAGravityBottomLeft //图片大小不做改变,图片和layer左上边对齐
-kCAGravityBottomRight //图片大小不做改变,图片和layer右上边对齐
-kCAGravityResize //图片大小会适应layer的frame大小
-kCAGravityResizeAspect//图片比例不变,按照宽高中较小的显示,小于frame
-kCAGravityResizeAspectFill //图片比例不变,按照宽高中较大的显示,大于frame

contentsScale

contentsScale 属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它 是一个值为1.0的浮点数。
其他在contentGravity的值为kCAGravityResize kCAGravityResizeAspect kCAGravityResizeAspectFill下不起作用,因为他们已经经过拉伸了,在其他作用下有效果。

maskToBounds

如果设为YES,超出layer边界的将不会显示,和UIView的clipsToBounds对应.
在contentGravity设置为kCAGravityResize和kCAGravityResizeAspect时不会发生裁剪,其他都有可能会被裁剪。

contentsRect

CALayer的 contentsRect 属性允许我们在图层边框里显示寄宿图的一个子域.contentsRect 不是按点来计算的,它使用了单位 坐标,单位坐标指定在0到1之间,是一个相对值.默认的 contentsRect 是{0, 0, 1, 1},这意味着整个寄宿图默认都是可见的,如果 我们指定一个小一点的矩形,图片就会被裁剪.


image.png

事实上给 contentsRect 设置一个负数的原点或是大于{1, 1}的尺寸也是可以的。
这种情况下,最外面的像素会被拉伸以填充剩下的区域。

    layer.contentsRect = CGRectMake(-0.1, -0.1, 0.5, 0.5);
image.png

contentsCenter

contentsCenter 其实是一个CGRect,它定义了一个固定的边框和一个在图 层上可拉伸的区域。 改变 contentsCenter 的值并不会影响到寄宿图的显示,除 非这个图层的大小改变了,你才看得到效果。默认情况下, 是{0, 0, 1, 1},这意味着如果大小(由 决定)改变了,那么寄宿图将会均匀地拉伸开。但是如果我 们增加原点的值并减小尺寸。我们会在图片的周围创造一个边框。下图展示了 contentsCenter 设置为{0.25, 0.25, 0.5, 0.5}的效果。


image.png

Custom Drawing

给 contents 赋CGImage的值不是唯一的设置寄宿图的方法。我们也可以直接 用Core Graphics直接绘制寄宿图。能够通过继承UIView并实现 -drawRect: 方法 来自定义绘制。-drawRect: 方法没有默认的实现,因为对UIView来说,寄宿图并不是必须 的,它不在意那到底是单调的颜色还是有一个图片的实例。如果UIView检测到 - drawRect: 方法被调用了,它就会为视图分配一个寄宿图,这个寄宿图的像素尺 寸等于视图大小乘以 contentsScale 的值。如果你不需要寄宿图,那就不要创建这个方法了,这会造成CPU资源和内存的浪 费,这也是为什么苹果建议:如果没有自定义绘制的任务就不要在子类中写一个空 的-drawRect:方法。
当视图在屏幕上出现的时候 -drawRect: 方法就会被自动调用。 -
drawRect: 方法里面的代码利用Core Graphics去绘制一个寄宿图,然后内容就会 被缓存起来直到它需要被更新(通常是因为开发者调用了 -setNeedsDisplay 方 法,尽管影响到表现效果的属性值被更改时,一些视图类型会被自动重绘,
如 bounds 属性)。虽然 -drawRect: 方法是一个UIView方法,事实上都是底层 的CALayer安排了重绘工作和保存了因此产生的图片。
CALayer有一个可选的 delegate 属性,实现了 CALayerDelegate 协议,当 CALayer需要一个内容特定的信息时,就会从协议中请求。CALayerDelegate是一 个非正式协议,其实就是说没有CALayerDelegate @protocol可以让你在类里面引 用啦。你只需要调用你想调用的方法,CALayer会帮你做剩下的。( delegate 属 性被声明为id类型,所有的代理方法都是可选的)。
当需要被重绘时,CALayer会请求它的代理给他一个寄宿图来显示。它通过调用 下面这个方法做到的:

- (void)displayLayer:(CALayer *)layer;

趁着这个机会,如果代理想直接设置contents属性的话,它就可以这么做, 不然没有别的方法可以调用了。如果代理不实现 CALayer就会转而尝试调用下面这个方法:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;

在调用这个方法之前,CALayer创建了一个合适尺寸的空寄宿图(尺寸
由 bounds 和 contentsScale 决定)和一个Core Graphics的绘制上下文环境, 为绘制寄宿图做准备,他作为ctx参数传入。

相关文章

  • CALayer寄宿图

    寄宿图 CALayer 类能够包含一张图片,这个图片就是CALayer寄宿图,用属性contents进行赋值。 c...

  • CALayer寄宿图

    什么是寄宿图? 简而言之就是图层(layer)中包含的图,这个图为了我们提供了能够去设置或者绘制出我们想要的图案显...

  • CALayer----寄宿图

    寄宿图 什么是寄宿图 图层中包含的 View 1. contents 属性 contents: 1> CALaye...

  • CALayer的寄宿图

    CALayer 有一个属性叫做contents,它可以直接在图层中放置一张图片 @property conte...

  • iOS核心动画高级技巧--(二)寄宿图

    这一章节我们将来探索 CALayer的寄宿图(即图层中包含的图)。 contents属性 CALayer有一个属性...

  • 第2章 寄宿图

    CALayer中包含的图就叫寄宿图,其中有个contents属性就是专门用来存放图片的 2.1 contents ...

  • iOS CALayer图层漫谈(二)

    上一篇《iOS CALayer图层漫谈(一)》我们聊了CALayer的基本的概念和有关寄宿图的一些属性,这一篇呢我...

  • [Core Animation] CALayer的寄宿图

    来自我的个人博客Minecode.link 寄宿图 我们都知道,视图可以导入图片,并设置其拉伸模式、放大比例之类。...

  • iOS动画相关笔记

    CALayer的属性 1 contents contents属性用来绘制寄宿图,它接受一个id类型,但是实际上接受...

  • 寄宿图

    看到这个名字可能会一脸懵逼,什么是寄宿图啊?简单的来说就是图层中包含的图。 contents属性 CALayer有...

网友评论

    本文标题:CALayer寄宿图

    本文链接:https://www.haomeiwen.com/subject/xgiwlktx.html