Core Animation 学习笔记 Layer基本属性

Core Animation 学习笔记

Layer的属性

CALayer 能帮助我们完成很多东西,那么先来看看他都有哪些基本属性吧。

添加图片 --- Contents属性

CALayer 有一个属性叫做contents,这个属性的类型被定义为id,意味着它可以是任何类型的对象。在这种情况下,你可以给contents属性赋任何值,你的app仍然能够编译通过。但是,在实践中,如果你给contents赋的不是CGImage,那么你得到的图层将是空白的。

contents这个奇怪的表现是由Mac OS的历史原因造成的。它之所以被定义为id类型,是因为在Mac OS系统上,这个属性对CGImage和NSImage类型的值都起作用。如果你试图在iOS平台上将UIImage的值赋给它,只能得到一个空白的图层。

事实上,你真正要赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。UIImage有一个CGImage属性,它返回一个"CGImageRef",如果你想把这个值直接赋值给CALayer的contents,那你将会得到一个编译错误。因为CGImageRef并不是一个真正的Cocoa对象,而是一个Core Foundation类型。

尽管Core Foundation类型跟Cocoa对象在运行时貌似很像(被称作toll-free bridging),他们并不是类型兼容的,不过你可以通过bridged关键字转换。如果要给图层的寄宿图赋值,你可以按照以下这个方法:

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

这个时候,我们如何给我们的UIView 添加一张图片呢。如下:

 - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.\
    
    UIView *layerView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:layerView];
    
    UIImage *image = [UIImage imageNamed:@"imageName"];
    
    //add it directly to our view's layer
    layerView.layer.contents = (__bridge id)image.CGImage;
}

这个时候 layerView 里面就会有一张 叫 imageName的图片。可以试着自己搞搞看。

ContentModel --- contentGravity属性

当显示的图片不符合要求的尺寸,在UIImageView 中也有这样的问题,而UIImageView是通过 ContentModel去解决的,那么在layer中一样有这样的属性。

CALayer与contentMode对应的属性叫做contentsGravity,但是它是一个NSString类型,而不是像对应的UIKit部分,那里面的值是枚举。contentsGravity可选的常量值有以下一些:

kCAGravityCenter

kCAGravityTop

kCAGravityBottom

kCAGravityLeft

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspectFill

和cotentMode一样,contentsGravity的目的是为了决定内容在图层的边界中怎么对齐,我们将使用kCAGravityResizeAspect,它的效果等同于UIViewContentModeScaleAspectFit, 同时它还能在图层中等比例拉伸以适应图层的边界。

contentsScale属性

contentsScale属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点数。

contentsScale的目的并不是那么明显。它并不是总会对屏幕上的寄宿图有影响。如果你尝试对我们的例子设置不同的值,你就会发现根本没任何影响。因为contents由于设置了contentsGravity属性,所以它已经被拉伸以适应图层的边界。

当用代码的方式来处理寄宿图的时候,一定要记住要手动的设置图层的contentsScale属性,否则,你的图片在Retina设备上就显示得不正确啦。代码如下:

layer.contentsScale = [UIScreen mainScreen].scale;

自定义Layer

给contents赋CGImage的值不是唯一的设置寄宿图的方法。我们也可以直接用Core Graphics直接绘制寄宿图。能够通过继承UIView并实现-drawRect:方法来自定义绘制

-drawRect: 方法没有默认的实现,因为对UIView来说,寄宿图并不是必须的,它不在意那到底是单调的颜色还是有一个图片的实例。如果UIView检测到-drawRect: 方法被调用了,它就会为视图分配一个寄宿图,这个寄宿图的像素尺寸等于视图大小乘以 contentsScale的值。

如果你不需要寄宿图,那就不要创建这个方法了,这会造成CPU资源和内存的浪费,这也是为什么苹果建议:如果没有自定义绘制的任务就不要在子类中写一个空的-drawRect:方法

当视图在屏幕上出现的时候 -drawRect:方法就会被自动调用。-drawRect:方法里面的代码利用Core Graphics去绘制一个寄宿图,然后内容就会被缓存起来直到它需要被更新(通常是因为开发者调用了-setNeedsDisplay方法,尽管影响到表现效果的属性值被更改时,一些视图类型会被自动重绘,如bounds属性)。虽然-drawRect:方法是一个UIView方法,事实上都是底层的CALayer安排了重绘工作和保存了因此产生的图片。

总结

介绍了一下CALay的许多属性。然后就是 如果要自定义layer的话,只要在UIView中实现drawRect方法,在这个方法里面打开图片上下文进行绘制。但是如果你没有要绘制的layer,请在代码中尽量不要实现drawRect方法,因为如果你实现了(即使是一个空方法),那么CUP也会给这个UIView分配一个空间去存储寄宿图,这样就造成了不必要的CUP浪费。

通常做法是实现UIView的-drawRect:方法,UIView就会帮你做完剩下的工作,包括在需要重绘的时候调用-display方法。

参考致谢

http://zsisme.gitbooks.io/ios-/content/chapter2/the-contents-image.html

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

推荐阅读更多精彩内容