CALayer 有许多内置的属性,这些属性可以帮助你方便地创造出各种静态特效,比如给图片加边框,制作圆角等。
我们先罗列 CALayer 的主要属性与方法,然后着重介绍其中的几个常用的静态视觉效果。
1 CALayer 的主要属性与方法
CALayer 的主要属性与方法1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| --------------- 绘图与显示 -------------
・内容 (比如设置为图片 CGImageRef) @property (retain) id contents;
・contentsGravity layer 上图片的拉伸方式 ・contentsScale layer 显示的拉伸比例 ・contentsRect 指定 layer 上显示图片的部分 ・contentsCenter 控制 layer 可拉伸的范围 ・masksToBounds:Bool 同 view 下的 clicpsToBounds,不显示超出范围的内容
• backgroundColor, opaque , opacity
--------------- 布局与定位 -------------- ・宽度和高度 @propertyCGRect bounds;
・位置 (默认指中点,具体由 anchorPoint 决定) @property CGPoint position;
・锚点 (x,y 的范围都是 0-1),决定了 position 的含义 @property CGPoint anchorPoint;
--------------- 显示与特效 --------------
・背景颜色 (CGColorRef 类型) @property CGColorRef backgroundColor;
・边框颜色 (CGColorRef 类型) @property CGColorRef borderColor;
・边框宽度 @property CGFloat borderWidth;
・圆角半径 @property CGFloat cornerRadius;
- shadowColor 阴影颜色 - shadowOpacity 阴影透明度 - shadowRadius 阴影半径 - shadowOffset 阴影的位移 - shadowPath 阴影形状(比如圆形的阴影)
--------------- 几何变形 --------------
・形变属性 @property CATransform3D transform;
|
2 backgroundColor, opaque , opacity
这几个属性与 UIView 的几个属性很相近。
layer 的这个属性与 view 是联动的,实际上设置 view 的 backgroundColor 就是在设置 layer 的 backgroundColor.
与 backgroundColor 一样,与 view 的 alpha 属性是联动的。
此属性不与 view 联动。主要控制 layer 的不透明效果。在绘图时使用 clear 方法时可见此效果,不透明的就显露底色(默认黑色),否则显示透明效果。这个属性与 View 一样,对提升 UI 性能有重要关系,在不影响显示的情况下,设置其为 YES,可以降低渲染复杂度,提升性能。
3 边框 - borders
3.1 主要属性
边框效果主要属性1 2 3
| borderWidth, borderColor, cornerRadius
cornerRadius - 设置 layer 边界圆角。
|
4 阴影 - shadows
与阴影有关的主要属性。要注意的是如果 view 使用了 clipsToBounds 为 YES,layer 设置了 marksToBounds 的话,阴影就显示不出来了
阴影 - shadows1 2 3 4 5 6 7
| shadowColor, shadowOpacity, shadowRadius, shadowOffset .
- shadowColor 阴影颜色 - shadowOpacity 阴影透明度 - shadowRadius 阴影半径 - shadowOffset 阴影的位移 - shadowPath 阴影形状(比如圆形的阴影)
|
4.1 示例 1 - 使用边框与阴影制作卡片
示例 1 - 使用边框与阴影制作卡片1 2 3 4 5 6 7 8 9
| UIView *cardView = [UIView new]; cardView.backgroundColor = [UIColor whiteColor]; cardView.layer.borderWidth = kAppDimension.lineWidth; cardView.layer.borderColor = kAppColor.dividerDark.CGColor; cardView.layer.cornerRadius = 6.0; cardView.layer.shadowColor = UIColor.blackColor.CGColor; cardView.layer.shadowOpacity = 0.5; cardView.layer.shadowRadius = 5.0; cardView.layer.shadowOffset = CGSizeMake(2, 4);
|
4.2 给图片加阴影
图层的阴影继承自内容的外形,而不是根据边界和角半径来确定。为了计算出阴影的形状,Core Animation 会将寄宿图(包括子视图,如果有的话)考虑在内,然后通过这些来完美搭配图层形状从而创建一个阴影。
从下面这个给图片加阴影的示例中我们可以看出,CA 会根据图片的内容自动生成对应的阴影!
给图片加阴影1 2 3 4 5 6 7 8 9 10
| CALayer *layer = [CALayer new]; layer.frame = CGRectMake(0, 0, 100, 100); UIImage *img = [UIImage imageNamed:@"rain"]; layer.contents = (id)img.CGImage; layer.shadowColor = UIColor.blackColor.CGColor; layer.shadowOpacity = 0.5; layer.shadowRadius = 5.0; layer.shadowOffset = CGSizeMake(2, 4); [frameView.layer addSublayer:layer]; [demo1 flex_addSubview:frameView];
|
5 图层蒙板 - masks
当设置一个图层为另一个图层的 mask 属性时,如 A.mask = B;
相当于声明图层 B 为 mask 图层。一个图层设置为 mask 图层后,其所有颜色信息都会忽略,只省一个轮廓。相当于以其为蒙板,用 B 的轮廓切割 A 图层,如下图:
示例,我们做一个渐变色的文字,实现效果可以在我的 iOSOneDemo 中对应这篇文章的章节查看。:
渐变色的文字1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.contentsScale = [UIScreen mainScreen].scale; gradientLayer.frame = CGRectMake(0, 0, 200, 30); [gradientLayer setStartPoint:CGPointMake(0.0, 0.5)]; [gradientLayer setEndPoint:CGPointMake(1.0, 0.5)]; gradientLayer.colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor yellowColor].CGColor,(id)[UIColor greenColor].CGColor];
CATextLayer *labelLayer =[CATextLayer layer]; labelLayer.contentsScale = [UIScreen mainScreen].scale; labelLayer.string = @"红黄绿渐变~~"; labelLayer.bounds = CGRectMake(0, 0, 200, 30); labelLayer.font = (__bridge CFTypeRef _Nullable)(@"HelveticaNeue-BoldItalic"); labelLayer.fontSize = 20.f; labelLayer.position = CGPointMake(100, 15); labelLayer.foregroundColor =[UIColor blackColor].CGColor;
UIView *layerFrame = [UIView new]; [layerFrame.layer addSublayer:gradientLayer]; gradientLayer.mask = labelLayer;
|
6 拉伸过滤
当我们视图显示一个图片的时候,都应该以正常的比例显示这个图片:
原因如下:
- 能够显示最好的画质,像素既没有被压缩也没有被拉伸。
- 能更好的使用内存,因为这就是所有你要存储的东西。
- 最好的性能表现,CPU 不需要为此额外的计算。
不过有时候,显示一个非真实大小的图片确实是我们需要的效果。比如说一个头像或是图片的缩略图,再比如说一个可以被拖拽和伸缩的大图。这些情况下,为同一图片的不同大小存储不同的图片显得又不切实际。
当图片需要显示不同的大小的时候,有一种叫做拉伸过滤的算法就起到作用了。 它作用于原图的像素上并根据需要生成新的像素显示在屏幕上。
6.1 minificationFilter 和 magnificationFilter 属性
CALayer 为此提供了三种拉伸过滤方法,他们是:
- kCAFilterLinear
- kCAFilterNearest
- kCAFilterTrilinear
minificationFilter 和 magnificationFilter 属性可以设置当缩小与放大图片时,使用哪个过滤器。
kCAFilterLinear,这个过滤器采用双线性滤波算法,它在大多数情况下都表 现良好。双线性滤波算法通过对多个像素取样最终生成新的值,得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清了。
kCAFilterTrilinear 与 kCAFilterLinear 非常相似,大部分情况下二者都 看不出来有什么差别。但是,较双线性滤波算法而言,三线性滤波算法存储了多个大小情况下的图片(也叫多重贴图),并三维取样,同时结合大图和小图的存储进而得到最后的结果。
kCAFilterNearest 是一种比较武断的方法。从名字不难看出,这个算法(也叫最近过滤)就是取样最近的单像素点而不管其他的颜色。这样做非常快,也不会使图片模糊。但是,最明显的效果就是,会使得压缩图片更糟,图片放大之后也显得块状或是马赛克严重。
简单地说就是 kCAFilterLinear 与 kCAFilterTrilinear 都会在缩放时通过增加一些插值颜色,使效果更平滑些。而 kCAFilterNearest 不会增加颜色,而会取最近的一个单色都填充或过滤。通常,如果颜色值较小,纯色较多,使用 kCAFilterNearest 效果更好;一般的多色彩的图片,使用前两者会更好。
7 引用
【1】[Matt Neuburg - 《Programming iOS deep into views,view controllers and frameworks》]
【2】[Nick LockWood - 《iOS Core Animation: Advanced Techniques》]