圓角
圓角矩形是iOS的一個標志性審美特性。這在iOS的每一個地方都得到了體現(xiàn),不論是主屏幕圖標,還是警告彈框,甚至是文本框。按照這流行程度,你可能會認為一定有不借助Photoshop就能輕易創(chuàng)建圓角舉行的方法。恭喜你,猜對了。
CALayer有一個叫做conrnerRadius的屬性控制著圖層角的曲率。它是一個浮點數(shù),默認為0(為0的時候就是直角),但是你可以把它設置成任意值。默認情況下,這個曲率值只影響背景顏色而不影響背景圖片或是子圖層。不過,如果把masksToBounds設置成YES的話,圖層里面的所有東西都會被截取。
具體使用如下:
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(150, 150, 100, 100)];
[self.view addSubview:view1];
//set the corner radius on our layers
view1.layer.cornerRadius = 20.0f;
//enable clipping on the second layer
view1.layer.masksToBounds = YES;
}
@end
邊框
CALayer另外兩個非常有用屬性就是borderWidth和borderColor。二者共同定義了圖層邊的繪制樣式。這條線(也被稱作stroke)沿著圖層的bounds繪制,同時也包含圖層的角。
borderWidth是以點為單位的定義邊框粗細的浮點數(shù),默認為0.borderColor定義了邊框的顏色,默認為黑色
borderColor是CGColorRef類型,而不是UIColor,所以它不是Cocoa的內(nèi)置對象。不過呢,你肯定也清楚圖層引用了borderColor,雖然屬性聲明并不能證明這一點。CGColorRef在引用/釋放時候的行為表現(xiàn)得與NSObject極其相似。但是Objective-C語法并不支持這一做法,所以CGColorRef屬性即便是強引用也只能通過assign關鍵字來聲明。
邊框是繪制在圖層邊界里面的,而且在所有子內(nèi)容之前,也在子圖層之前。
也就是 只要設置 borderColor和 borderWidth 屬性就能設置一個View的邊框
陰影
在iOS中陰影的設置有4個屬性,shadowOpacity,shadowColor,shadowOffset,shadowRadius.
給shadowOpacity屬性一個大于默認值(也就是0)的值,陰影就可以顯示在任意圖層之下。shadowOpacity是一個必須在0.0(不可見)和1.0(完全不透明)之間的浮點數(shù)。如果設置為1.0,將會顯示一個有輕微模糊的黑色陰影稍微在圖層之上。若要改動陰影的表現(xiàn),你可以使用CALayer的另外三個屬性:shadowColor,shadowOffset和shadowRadius。
shadowColor控制著陰影的顏色,shadowOffset控制著陰影的偏移量,shadowRadius是一個模糊程度的概念。
shadowColor 是一個CGColor
shadowOffset 是一個CGSize,默認是(0,-3)對Y軸有默認3個點的偏移量
shadowRadius 控制著陰影的模糊度,是一個CGFloat,越大越模糊,
陰影裁剪
和圖層邊框不同,圖層的陰影繼承自內(nèi)容的外形,而不是根據(jù)邊界和角半徑來確定。為了計算出陰影的形狀,Core Animation會將寄宿圖(包括子視圖,如果有的話)考慮在內(nèi),然后通過這些來完美搭配圖層形狀從而創(chuàng)建一個陰影.
所以 陰影是根據(jù)寄宿圖的輪廓來確定的。
圖層蒙板
通過masksToBounds屬性,我們可以沿邊界裁剪圖形;通過cornerRadius屬性,我們還可以設定一個圓角。但是我們?nèi)绻氲玫揭粋€ 不規(guī)則圖形呢,該怎么辦。
CALayer有一個屬性叫做mask可以解決這個問題。這個屬性本身就是個CALayer類型,有和其他圖層一樣的繪制和布局屬性。它類似于一個子圖層,相對于父圖層(即擁有該屬性的圖層)布局,但是它卻不是一個普通的子圖層。不同于那些繪制在父圖層中的子圖層,mask圖層定義了父圖層的部分可見區(qū)域。
mask圖層的Color屬性是無關緊要的,真正重要的是圖層的輪廓。mask屬性就像是一個餅干切割機,mask圖層實心的部分會被保留下來,其他的則會被拋棄。(如圖4.12)
如果mask圖層比父圖層要小,只有在mask圖層里面的內(nèi)容才是它關心的,除此以外的一切都會被隱藏起來。
實現(xiàn)上面的代碼如下:
@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