[iOS Animation]-CALayer 視覺效果-shadowPath屬性

shadowPath屬性

咱們已經知道圖層陰影並不老是方的,而是從圖層內容的形狀繼承而來。這看上去不錯,可是實時計算陰影也是一個很是消耗資源的,尤爲是圖層有多個子圖層,每一個圖層還有一個有透明效果的寄宿圖的時候。 git

若是你事先知道你的陰影形狀會是什麼樣子的,你能夠經過指定一個shadowPath來提升性能。shadowPath是一個CGPathRef類型(一個指向CGPath的指針)。CGPath是一個Core Graphics對象,用來指定任意的一個矢量圖形。咱們能夠經過這個屬性單獨於圖層形狀以外指定陰影的形狀。 github

圖4.11 展現了同一寄宿圖的不一樣陰影設定。如你所見,咱們使用的圖形很簡單,可是它的陰影能夠是你想要的任何形狀。清單4.4是代碼實現。 app

圖4.11

圖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

圖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

圖4.13 使用了mask以後的UIImageView

CALayer蒙板圖層真正厲害的地方在於蒙板圖不侷限於靜態圖。任何有圖層構成的均可以做爲mask屬性,這意味着你的蒙板能夠經過代碼甚至是動畫實時生成。

相關文章
相關標籤/搜索