筆者在學習CALayer的時候,從 文頂頂 、TerryLMay、GitBook等地方學到了很多東西,在此將要分享的內(nèi)容基本上是對我所學內(nèi)容的總結(jié)。感謝前人的分享,也希望各位看官不吝賜教。如果有侵犯到原作者的權(quán)益,請及時告知。
CALayer的簡單介紹
- 在iOS中,你能看得見摸得著的東西基本上都是UIView,比如一個按鈕、一個文本標簽、一個文本輸入框、一個圖標等等,這些都是UIView。
- 其實UIView之所以能顯示在屏幕上,完全是因為它內(nèi)部的一個圖層,在創(chuàng)建UIView對象時,UIView內(nèi)部會自動創(chuàng)建一個圖層(即CALayer對象),通過UIView的layer屬性可以訪問這個層:
@property(nonatomic,readonly,retain) CALayer *layer;
- 當UIView需要顯示到屏幕上時,會調(diào)用drawRect:方法進行繪圖,并且會將所有內(nèi)容繪制在自己的圖層上,繪圖完畢后,系統(tǒng)會將圖層拷貝到屏幕上,于是就完成了UIView的顯示。
- 換句話說,UIView本身不具備顯示的功能,擁有顯示功能的是它內(nèi)部的圖層。
- UIView之所以能夠顯示,完全是因為內(nèi)部的CALayer對象。因此,通過操作這個CALayer對象,可以很方便地調(diào)整UIView的一些界面屬性,比如:陰影、圓角大小、邊框?qū)挾群皖伾取?/li>
- 注意:layer中不能直接接受UI框架中的東西
內(nèi)容
- 通過 layer 設(shè)置邊框的寬度和顏色
- 通過 layer 設(shè)置邊框為圓角
- 在 layer 上添加一張圖片
- 設(shè)置超出子圖層的部分裁減掉
- 設(shè)置陰影
- 只要繼承自 UIView 的都有 layer 屬性
- 通過屬性設(shè)置圖片形變
- 通過KVC來設(shè)置形變
- 設(shè)置旋轉(zhuǎn)
準備工作
本次講解的所有代碼都是寫在控制器里面的,我們需要在storyBoard里面先拖兩個控件:
@property (weak, nonatomic) IBOutlet UIView *customView;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
然后,我們開始講解代碼。
1.通過 layer 設(shè)置邊框的寬度和顏色

實現(xiàn)代碼:
- (void)setWidthAndColor
{
// 設(shè)置邊框的寬度為20
self.customView.layer.borderWidth = 5;
// 設(shè)置邊框的顏色
self.customView.layer.borderColor = [UIColor blackColor].CGColor;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
2.通過 layer 設(shè)置邊框為圓角

實現(xiàn)代碼:
- (void)setCornerRadius
{
self.customView.layer.borderWidth = 5;
self.customView.layer.borderColor = [UIColor blackColor].CGColor;
// 設(shè)置layer的圓角
self.customView.layer.cornerRadius = 20;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
3.在 layer 上添加一張圖片

實現(xiàn)代碼:
- (void)addImage
{
self.customView.layer.borderWidth = 5;
self.customView.layer.borderColor = [UIColor blackColor].CGColor;
self.customView.layer.cornerRadius = 20;
// 在view的圖層上添加一個image,contents表示接受內(nèi)容
// contents是id類型,可以接受內(nèi)容,下面的實例讓layer顯示一張圖片
self.customView.layer.contents = (id)[UIImage imageNamed:@"AI_200*200"].CGImage;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
但是觀察可發(fā)現(xiàn)四個圓角部分露了一個角出來,產(chǎn)生原因說明:




那是因為設(shè)置的image不是展示在主圖層上的,而是顯示在子圖層上的??梢酝ㄟ^設(shè)置一個范圍,設(shè)置超出主圖層的部分把它給剪切掉。
4.設(shè)置超出子圖層的部分裁減掉

實現(xiàn)代碼:
- (void)setCut
{
self.customView.layer.borderWidth = 5;
self.customView.layer.borderColor = [UIColor blackColor].CGColor;
self.customView.layer.cornerRadius = 20;
// 設(shè)置超出子視圖的部分裁減掉
// UI框架中使用的方法
// self.customView.clipsToBounds = YES;
self.customView.layer.masksToBounds = YES;//建議使用這一種
self.customView.layer.contents = (id)[UIImage imageNamed:@"AI_200*200"].CGImage;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
5.設(shè)置陰影

實現(xiàn)代碼:
- (void)setShadow
{
/**
* 設(shè)置陰影,不光需要設(shè)置陰影顏色,還應該設(shè)置陰影的偏移位和透明度。
* 因為如果不設(shè)置偏移位的話,那么陰影和layer完全重疊,且默認透明度為0(即完全透明)。
*/
// 注意:如果設(shè)置了超過主圖層的部分減掉,則設(shè)置陰影不會有顯示效果。
// 設(shè)置陰影顏色
self.customView.layer.shadowColor = [UIColor blackColor].CGColor;
// 設(shè)置陰影的偏移量,如果為正數(shù),則代表為往右下偏移
self.customView.layer.shadowOffset = CGSizeMake(15, 5);
// 設(shè)置陰影的透明度(0~1之間,0表示完全透明)
self.customView.layer.shadowOpacity = 0.6;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
6.只要繼承自 UIView 的都有 layer 屬性

實現(xiàn)代碼:
- (void)configImageView
{
self.iconView.layer.borderColor = [UIColor brownColor].CGColor;
self.iconView.layer.borderWidth = 5;
self.iconView.layer.cornerRadius = 20;
self.iconView.layer.masksToBounds = YES;
}
在viewDidLoad方法里進行調(diào)用就可以實現(xiàn)。
7.通過屬性設(shè)置圖片形變

在viewDidLoad調(diào)用 -configImageView 方法。
實現(xiàn)代碼:
- (void)setTransform
{
// 通過UIView來設(shè)置(2D效果)
// self.iconView.transform = CGAffineTransformMakeTranslation(0, -100);
// 通過layer來設(shè)置(3D效果,x,y,z三個方向)
self.iconView.layer.transform = CATransform3DMakeTranslation(100, 20, 0);
}
在touchesBegan:withEvent:方法里面調(diào)用就可以實現(xiàn)。
8.通過KVC來設(shè)置形變

在viewDidLoad調(diào)用 -configImageView 方法。
實現(xiàn)代碼:
- (void)setTransformByKVC
{
// 通過KVC來設(shè)置
NSValue *v = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(100, 20, 0)];
[self.iconView.layer setValue:v forKey:@"transform"];
// 如果只需要設(shè)置在某一個方向上的移動,可以參考下面代碼
// 在x方向上向左移動100
// [self.iconView.layer setValue:@(-100) forKey:@"transform.translation.x"];
}
在touchesBegan:withEvent:方法里面調(diào)用就可以實現(xiàn)。
9.設(shè)置旋轉(zhuǎn)

在viewDidLoad調(diào)用 -configImageView 方法。
實現(xiàn)代碼:
- (void)setRotation
{
// 旋轉(zhuǎn)
self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_4, 1, 1, 0.5);
}
在touchesBegan:withEvent:方法里面調(diào)用就可以實現(xiàn)。