容易忽略的那些小点总结 (三) —— CALayer相关(二)

版本记录

版本号 时间
V1.0 2018.01.22

前言

在苹果的API文档中,有很多属性和方法我们用的不是很多,所以很容易忽略和出错,下面我就用这一个专题专门说一些不常用的API接口,下面开始。感兴趣的可以参考前面几篇文章。
1. 容易忽略的那些小点总结 (一) —— UIView UIViewTintAdjustmentMode相关(一)
2. 容易忽略的那些小点总结 (二) —— CALayer相关(一)

- (BOOL)shouldArchiveValueForKey:(NSString *)key;

首先还是先看一下这个方法的API文档

/* Called by the object's implementation of -encodeWithCoder:, returns
 * false if the named property should not be archived. The base
 * implementation returns YES. Subclasses should call super for
 * unknown properties. 

    由对象的-encodeWithCoder:的实现调用,如果命名属性不应归档,则返回false。 
    可以归档返回YES。 对于未知属性子类应该调用父类方法。
*/

- (BOOL)shouldArchiveValueForKey:(NSString *)key;

这个方法其实就是,如果该对象中的属性如果可以归档就返回YES,否则返回NO,是由方法-encodeWithCoder:进行调用的。


geometryFlipped

/* Whether or not the geometry of the layer (and its sublayers) is
 * flipped vertically. Defaults to NO. Note that even when geometry is
 * flipped, image orientation remains the same (i.e. a CGImageRef
 * stored in the `contents' property will display the same with both
 * flipped=NO and flipped=YES, assuming no transform on the layer). 

  层(及其子层)的几何是否垂直翻转。 默认为NO。 请注意,即使在翻转几何图形时,
  图像方向仍保持不变(即,假设在图层上没有变换,则存储在“contents”属性中的CGImageRef
  将在flipped=NO and flipped=YES时显示相同)。
*/

@property(getter=isGeometryFlipped) BOOL geometryFlipped;

其实,这个属性用来判断当前layer是否可以垂直翻转,默认是NO,但是不管怎么翻转,图层中的图像是不会跟着翻转的。

  • 如果设置为yes,则子图层或者子视图本来相对于左上角放置改为相对于左下角放置。也可以这么理解geometryFlipped决定了一个图层的坐标是否相对于父图层垂直翻转,默认情况下是NO,也就是从左上角开始绘制,当把值改为YES的时候这个图层和他的子图层将会被垂直翻转,也就是从左下角开始绘制。

  • 该属性可以改变默认图层y坐标的方向。当翻转变换被调用时,使用该属性来调整图层的方向有的时候是必需的。如果父视图使用了翻转变换,它的子视图内容(以及它对应的图层)将经常被颠倒。在这种情况下,设置子图层的geometryFlipped属性为YES是一种修正该问题最简单的方法,但是一般不推荐使用geometryFlipped属性。


contentsAreFlipped

/* Returns true if the contents of the contents property of the layer
 * will be implicitly flipped when rendered in relation to the local
 * coordinate space (e.g. if there are an odd number of layers with
 * flippedGeometry=YES from the receiver up to and including the
 * implicit container of the root layer). Subclasses should not attempt
 * to redefine this method. When this method returns true the
 * CGContextRef object passed to -drawInContext: by the default
 * -display method will have been y- flipped (and rectangles passed to
 * -setNeedsDisplayInRect: will be similarly flipped). 
*/

  如果图层的content属性的内容在相对于局部坐标空间渲染时将被隐式地翻转(例如,如果从接收者
  直到并包括根层的隐式容器,有一个奇数层的flippedGeometry = YES),那就返回TRUE。 子类不应该
  尝试重新定义这个方法。 当这个方法返回true时,通过默认的-display方法传递给-drawInContext的
  CGContextRef对象将会被y翻转(传递给-setNeedsDisplayInRect的矩形将被类似地翻转)。

- (BOOL)contentsAreFlipped;

也可以这么理解:

  • 如果渲染时,图层的content被隐式的翻转就返回YES,否则返回NO。这个方法默认是返回NO的。这个方法提供了关于在绘制过程中图层内容是否被翻转的信息,你不应该尝试重写给方法返回一个不同的值,如果layer需要翻转它的content,那么就返回YES,那么在传递给图层drawInContext:方法之前,就对当前上下文实施y方向上的翻转,类似的,该图层将传递给其 setNeedsDisplayInRect:的所有矩形转换为翻转的坐标空间。

mask

/* A layer whose alpha channel is used as a mask to select between the
 * layer's background and the result of compositing the layer's
 * contents with its filtered background. Defaults to nil. When used as
 * a mask the layer's `compositingFilter' and `backgroundFilters'
 * properties are ignored. When setting the mask to a new layer, the
 * new layer must have a nil superlayer, otherwise the behavior is
 * undefined. Nested masks (mask layers with their own masks) are
 * unsupported. */

  将其alpha通道用作蒙版的图层,以在图层的背景和将图层内容与其过滤背景进行合成的结果
  之间进行选择。 默认为nil。 当用作蒙板时,图层的“compositingFilter”和
  “backgroundFilters”属性将被忽略。 将遮罩设置为新图层时,新图层必须有一个nil的图层,
  否则行为未定义。 不支持嵌套蒙版(带有自己蒙版的蒙版图层)。

@property(nullable, strong) CALayer *mask;

也可以这么理解:

  • 是一个可选的layer,它的alpha通道用于遮罩图层的内容。图层的Alpha通道决定了有多少的图层的内容和背景的显示通过。 完全或部分不透明的像素允许底层内容显示,但完全透明的像素屏蔽该内容。

  • 这个属性的默认值是nil。 配置mask时,请记得设置遮罩层的大小和位置,以确保遮罩层与它遮罩的层正确对齐。

  • 您分配给此属性的图层不能有父图层。否则行为是不确定的。

  • 遮罩层必须至少有两个图层,上面的一个图层为“遮罩层”,下面的称“被遮罩层”;这两个图层中只有相重叠的地方才会被显示。也就是说在遮罩层中有对象的地方就是“透明”的,可以看到被遮罩层中的对象,而没有对象的地方就是不透明的,被遮罩层中相应位置的对象是看不见的。

看一个示例代码

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = CGRectMake(100, 300, 200, 25);
    [gradientLayer setStartPoint:CGPointMake(0.0, 0.0)];
    [gradientLayer setEndPoint:CGPointMake(0.0, 1.0)];
    gradientLayer.colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor yellowColor].CGColor,(id)[UIColor blueColor].CGColor];
    
    UILabel *label = [[UILabel alloc] initWithFrame:gradientLayer.bounds];
    label.text = @"红黄蓝渐变~~";
    label.font = [UIFont boldSystemFontOfSize:25];
    label.backgroundColor = [UIColor clearColor];
    [self.view addSubview:label];
    
    [self.view.layer addSublayer:gradientLayer];
    gradientLayer.mask = label.layer;
}

@end

下面看一下实现效果


这里label的layer是mask,有对象的地方就是文字的部分,有文字的地方是透明的,就可以看见被其遮罩的渐变层gradientLayer的内容,而没有对象的部门是不透明的,所以文字外面就看不到其遮罩的渐变层gradientLayer的内容。


contentsRect

/* A rectangle in normalized image coordinates defining the
 * subrectangle of the `contents' property that will be drawn into the
 * layer. If pixels outside the unit rectangles are requested, the edge
 * pixels of the contents image will be extended outwards. If an empty
 * rectangle is provided, the results are undefined. Defaults to the
 * unit rectangle [0 0 1 1]. Animatable. */

@property CGRect contentsRect;

标准化的图像坐标中的矩形定义了将被绘制到图层中的“contents”属性的子矩形。 
如果需要单位矩形外的像素,则内容图像的边缘像素将向外扩展。 如果提供了
一个空的矩形,结果是不确定的。 默认为单位矩形[0 0 1 1]。可动画

也可以这么理解

  • 想像下contentsRect作为层内容的可视区域。内容的矩形区域(x,y,width,height)也是绑定到层的框架上的。contentRect是一个比例值,而不是屏幕上真实的像素点。默认的是0.0,0.0,1.0,1.0.当你改变x时,例如,在0和1之间你设定为0.25,那么内容的观察窗口就展示在400像素中的100像素的位置(400 x 0.25),也就是一个层原始宽度的25%。如果你设定了width属性为0.25,那么观察窗口的宽度就是100,也就是一个层原始宽度的25%。图2-1和2-2演示了contentsRect如何展示原始的图像层的区域。

参考文章

1. 小议contentsRect
2. 第二章 哪些我们可以和应该做动画哪?

后记

本篇已结束,后面更精彩~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容