咱们已经知道图层阴影并不老是方的,而是从图层内容的形状继承而来。这看上去不错,可是实时计算阴影也是一个很是消耗资源的,尤为是图层有多个子图层,每一个图层还有一个有透明效果的寄宿图的时候。 git
若是你事先知道你的阴影形状会是什么样子的,你能够经过指定一个shadowPath来提升性能。shadowPath是一个CGPathRef类型(一个指向CGPath的指针)。CGPath是一个Core Graphics对象,用来指定任意的一个矢量图形。咱们能够经过这个属性单独于图层形状以外指定阴影的形状。 github
图4.11 展现了同一寄宿图的不一样阴影设定。如你所见,咱们使用的图形很简单,可是它的阴影能够是你想要的任何形状。清单4.4是代码实现。 app
图4.11 用shadowPath指定任意阴影形状 框架
清单4.4 建立简单的阴影形状 布局
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
|
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *layerView1;
@property (nonatomic, weak) IBOutlet UIView *layerView2;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//enable layer shadows
self.layerView1.layer.shadowOpacity = 0.5f;
self.layerView2.layer.shadowOpacity = 0.5f;
//create a square shadow
CGMutablePathRef squarePath = CGPathCreateMutable();
CGPathAddRect(squarePath, NULL, self.layerView1.bounds);
self.layerView1.layer.shadowPath = squarePath; CGPathRelease(squarePath);
//create a circular shadow
CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);
self.layerView2.layer.shadowPath = circlePath; CGPathRelease(circlePath);
}
@end
|
若是是一个矩形或者是圆,用CGPath会至关简单明了。可是若是是更加复杂一点的图形,UIBezierPath类会更合适,它是一个由UIKit提供的在CGPath基础上的Objective-C包装类。 性能
经过masksToBounds属性,咱们能够沿边界裁剪图形;经过cornerRadius属性,咱们还能够设定一个圆角。可是有时候你但愿展示的内容不是在一个矩形或圆角矩形。好比,你想展现一个有星形框架的图片,又或者想让一些古卷文字慢慢渐变成背景色,而不是一个突兀的边界。 动画
使用一个32位有alpha通道的png图片一般是建立一个无矩形视图最方便的方法,你能够给它指定一个透明蒙板来实现。可是这个方法不能让你以编码的方式动态地生成蒙板,也不能让子图层或子视图裁剪成一样的形状。 ui
CALayer有一个属性叫作mask能够解决这个问题。这个属性自己就是个CALayer类型,有和其余图层同样的绘制和布局属性。它相似于一个子图层,相对于父图层(即拥有该属性的图层)布局,可是它却不是一个普通的子图层。不一样于那些绘制在父图层中的子图层,mask图层定义了父图层的部分可见区域。 编码
mask图层的Color属性是可有可无的,真正重要的是图层的轮廓。mask属性就像是一个饼干切割机,mask图层实心的部分会被保留下来,其余的则会被抛弃。(如图4.12) atom
若是mask图层比父图层要小,只有在mask图层里面的内容才是它关心的,除此之外的一切都会被隐藏起来。
图4.12 把图片和蒙板图层做用在一块儿的效果
咱们将代码演示一下这个过程,建立一个简单的项目,经过图层的mask属性来做用于图片之上。为了简便一些,咱们用Interface Builder来建立一个包含UIImageView的图片图层。这样咱们就只要代码实现蒙板图层了。清单4.5是最终的代码,图4.13是运行后的结果。
清单4.5 应用蒙板图层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//create mask layer
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = self.layerView.bounds;
UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
maskLayer.contents = (__bridge id)maskImage.CGImage;
//apply mask to image layer
self.imageView.layer.mask = maskLayer;
}
@end
|
图4.13 使用了mask以后的UIImageView
CALayer蒙板图层真正厉害的地方在于蒙板图不局限于静态图。任何有图层构成的均可以做为mask属性,这意味着你的蒙板能够经过代码甚至是动画实时生成。