CALayer(一)

CALayer并不清楚具体的响应链,并不能够响应事件,即时提供了一些方法来判断是否一个触点在图层的范围之内。

一、寄宿图

CALayer类可以包含一张图片,即寄宿图(图层中包含的图)。

(1)contents属性

此属性类型被定义为id,原则上给它赋值任何值,app仍能编译成功,但事实是如果给contents赋的不是CGImage,那么得到的图层将会是空白的。之所以这个属性被定义为id类型,是因为在Mac OS系统上,这个属性对CGImage和NSImage类型的值都起作用。

给图层的寄宿图赋值时,需要通过bridge关键字转换,例如:

layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"1.jpg"].CGImage);

用此属性赋值图片,图片可能显示得不是很正常,比如拉伸,好像被压缩的样子;若是用UIImageView赋值的话,解决此问题就是设置contentMode属性;

在CALayer中与contentMode对应的属性叫做contentsGravity,是个NSString类型,可选的常量值有:

kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspectFill

(2)contentScale

定义了寄宿图额像素尺寸和视图比例大小,默认情况下是一个值为1.0的浮点数。但是此属性并不是总会对屏幕上的寄宿图有影响;这是因为contents由于设置了contentsGravity属性,

如果只是想单纯的放大图层的contents图片,可以使用图层的transform和affineTransform属性来达到效果。

如果contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果设置为2.0,则会以每个点2个像素绘制图片,这就是我们熟知的Retina屏幕。

(3)maskToBounds

在有些情况下,图片会超出控件的边界,在UIView有一个clipsToBounds的属性可以用来决定是否显示超出边界内容,CALayer对应的属性为maskToBounds

(4)contentsRect

此属性可以在图层边框里显示寄宿图的一个子域,比contentsGravity灵活得多;contentsRect使用的是单位坐标,其值为0到1。

(5)contentsCenter

此属性为CGRect类型,它定义了一个固定的边框和一个在图层上可拉伸的区域。 改变contentsCenter的值并不会影响到寄宿图的显示,除非这个图层的大小改变了。

默认情况下,contentsCenter是{0, 0, 1, 1}。

设置此属性显示的效果和UIImage里的-resizableImageWithCapInsets: 方法效果非常类似。

二、布局

CALayer中的布局属性有frame、bounds、position;center和position都代表了相对于父图层anchorPoint(锚点)所在的位置。

(1)锚点

图层的anchorPoint通过position来控制它的frame的位置;默认坐标是{0.5, 0.5}.

(2)Hit Testing

CALayer虽然不能响应事件,但是拥有一些方法可以处理事件:

-containsPoint:如果这个点在图层frame范围内就返回YES

-hitTest:此方法接收一个CGPoint类型参数,返回的是图层本身,或者包含这个坐标点的叶子节点图层,注意当调用图层的-hitTest:方法时,测算的顺序严格依赖于图层树当中的图层顺序(和UIView处理事件类似)。

(3)自动布局

若是想要控制CALayer的布局,最简单的方法就是用CALayerDelegate如下函数:

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

当图层的bounds发生改变,或者图层的-setNeedsLayout方法被调用的时候,这个函数将会被执行。

 

参考自iOS Core Animation;

posted @ 2016-09-19 16:38  简简单单0  阅读(302)  评论(0编辑  收藏  举报