1悼枢、CALayer簡(jiǎn)單介紹
1馒索、在iOS中旨怠,你能看得見(jiàn)摸得著的東西基本上都是UIView蜈块,比如一個(gè)按鈕鉴腻、一個(gè)文本標(biāo)簽、一個(gè)文本輸入框百揭、一個(gè)圖標(biāo)等等爽哎,這些都是UIView
其實(shí)UIView之所以能顯示在屏幕上,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層
在創(chuàng)建UIView對(duì)象時(shí)器一,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象)课锌,通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層
@property(nonatomic,readonly,retain) CALayer*layer;
當(dāng)UIView需要顯示到屏幕上時(shí),會(huì)調(diào)用drawRect:方法進(jìn)行繪圖祈秕,并且會(huì)將所有內(nèi)容繪制在自己的圖層上渺贤,繪圖完畢后,系統(tǒng)會(huì)將圖層拷貝到屏幕上请毛,于是就完成了UIView的顯示
換句話說(shuō)获印,UIView本身不具備顯示的功能,是它內(nèi)部的層才有顯示功能
通過(guò)操作CALayer對(duì)象,可以很方便地調(diào)整UIView的一些外觀屬性,比如:陰影【如果設(shè)置了超過(guò)主圖層的部分減掉,則設(shè)置陰影不會(huì)有顯示效果;設(shè)置陰影墨吓,不光需要設(shè)置陰影顏色秘症,還應(yīng)該設(shè)置陰影的偏移位和透明度趟卸。因?yàn)槿绻辉O(shè)置偏移位的話邻邮,那么陰影和layer完全重疊鸭蛙,且默認(rèn)透明度為0(即完全透明)】肪获、圓角大小青柄、邊框?qū)挾群皖伾⑦€可以給圖層添加動(dòng)畫(huà),來(lái)實(shí)現(xiàn)一些比較炫酷的效果等等
2膏斤、CALayer是定義在QuartzCore
框架中的沮榜,CGImageRef
型酥、CGColorRef
兩種數(shù)據(jù)類型是定義在CoreGraphics
框架中的;UIColor
拒担、UIImage
是定義在UIKi
t框架中的
QuartzCore
框架和CoreGraphics
框架是可以跨平臺(tái)使用的,在iOS和MacOS X上都能使用(C語(yǔ)言編寫(xiě))但是UIKit
只能在iOS中使用(Objective-C)
為了保證可移植性,QuartzCore
不能使用UIImage
最蕾、UIColor
慷嗜,只能使用CGImageRef
洪添、CGColorRef
導(dǎo)入其他框架的方式: 選中項(xiàng)目, 在General
中找 Linked Frameworks and Libraries
添加對(duì)應(yīng)的框架
2、UIView和CALayer之間的區(qū)別
1、UIView是用來(lái)顯示內(nèi)容的,可以處理用戶事件刁愿。直接繼承UIResponser脑题。
2凿叠、CALayer是用來(lái)繪制內(nèi)容的,不能處理用戶事件片吊。直接集成NSObject绽昏。
3、 UIView和CALayer是相互依賴的關(guān)系俏脊。UIView依賴于calayer提供的內(nèi)容全谤,CALayer依賴UIView提供的容器來(lái)顯示繪制的內(nèi)容。歸根到底CALayer是這一切的基礎(chǔ)爷贫,如果沒(méi)有CALayer认然,UIView自身也不會(huì)存在,UIView是一個(gè)特殊的CALayer實(shí)現(xiàn)漫萄,添加了響應(yīng)事件的能力卷员。兩者之間是依存的關(guān)系.UIView可以通過(guò)subviews屬性訪問(wèn)所有的子視圖,類似地腾务,CALayer也可以通過(guò)sublayers屬性訪問(wèn)所有的子層毕骡; UIView可以通過(guò)superview屬性訪問(wèn)父視圖,類似地岩瘦,CALayer也可以通過(guò)superlayer屬性訪問(wèn)父層未巫。如果一個(gè)控件是另外一個(gè)控件的子控件,那么這個(gè)控件的layer也是另一個(gè)控件的子layer
結(jié)論:UIView來(lái)自CALayer启昧,高于CALayer橱赠,是CALayer高層實(shí)現(xiàn)與封裝。UIView的所有特性來(lái)源于CALayer支持箫津。
3狭姨、CALayer的常用屬性
寬度和高度
@property CGRect bounds;
位置(默認(rèn)指中點(diǎn)宰啦,具體由anchorPoint決定)
@property CGPoint position;
錨點(diǎn)(x,y的范圍都是0-1),決定了position的含義
@property CGPoint anchorPoint;
背景顏色(CGColorRef類型)
@propertyCGColorRefbackgroundColor;
形變屬性
@property CATransform3D transform;
邊框顏色(CGColorRef類型)
@property CGColorRef borderColor;
邊框?qū)挾?@property CGFloat borderWidth;
圓角半徑
@property CGFloat cornerRadius;
內(nèi)容(比如設(shè)置為圖片CGImageRef)
@property(retain) id contents;
說(shuō)明:可以通過(guò)設(shè)置contents屬性給UIView設(shè)置背景圖片
self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"123"].CGImage); 跨框架賦值需要進(jìn)行橋接
4饼拍、代碼示例
4.1CALayer的陰影效果
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) CALayer *myLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加到控制器的視圖之中
[self.view.layer addSublayer:self.myLayer];
// 設(shè)置圖層的內(nèi)容
self.myLayer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"123"].CGImage);
// 設(shè)置陰影的顏色
self.myLayer.shadowColor = [UIColor blackColor].CGColor;
// 設(shè)置陰影的便宜
self.myLayer.shadowOffset = CGSizeMake(15, 10);
// 設(shè)置陰影的不透明度
self.myLayer.shadowOpacity = 0.6;
// 設(shè)置邊角半徑
self.myLayer.cornerRadius = 15;
// 設(shè)置裁剪
self.myLayer.masksToBounds = YES;
// 設(shè)置邊框線的顏色
self.myLayer.borderColor = [UIColor blackColor].CGColor;
// 設(shè)置邊框線條的寬度
self.myLayer.borderWidth = 5.0;
}
-(CALayer *)myLayer{
if (_myLayer ==nil) {
// 創(chuàng)建layer對(duì)象
_myLayer = [CALayer layer];
// 設(shè)置圖層的frame
_myLayer.frame = CGRectMake(50, 100, 190, 145);
// 設(shè)置背景顏色
_myLayer.backgroundColor = [UIColor blackColor].CGColor;
self.myLayer = _myLayer;
}
return _myLayer;
}
@end
4.1運(yùn)行效果
設(shè)置陰影效果和裁剪邊角的效果是沖突的赡模,如果設(shè)置裁剪邊角那么陰影效果無(wú)法實(shí)現(xiàn);當(dāng)注釋掉裁剪邊框的效果师抄,陰影效果才顯示
4.2position和anchorPoint屬性
CALayer有2個(gè)非常重要的屬性:position和anchorPoint
@property CGPoint position;
用來(lái)設(shè)置CALayer在父層中的位置
以父層的左上角為原點(diǎn)(0, 0)
@property CGPoint anchorPoint;稱為“定位點(diǎn)”漓柑、“錨點(diǎn)”
決定著CALayer身上的哪個(gè)點(diǎn)會(huì)在position屬性所指的位置
以自己的左上角為原點(diǎn)(0, 0),它的x叨吮、y取值范圍都是0~1辆布,默認(rèn)值為(0.5, 0.5)
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) CALayer *myLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view.layer addSublayer:self.myLayer];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
self.myLayer.anchorPoint = CGPointMake(0, 0);
}
-(CALayer *)myLayer{
if (_myLayer ==nil) {
_myLayer = [CALayer layer];
_myLayer.frame = CGRectMake(100, 100, 100, 100);
_myLayer.backgroundColor = [UIColor redColor].CGColor;
self.myLayer = _myLayer;
}
return _myLayer;
}
@end
4.3隱式動(dòng)畫(huà)
每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer,我們可稱這個(gè)Layer為RootLayer(根層)
所有的非RootLayer茶鉴,也就是手動(dòng)創(chuàng)建的CALayer對(duì)象锋玲,都存在著隱式動(dòng)畫(huà)
什么是隱式動(dòng)畫(huà)?
當(dāng)對(duì)非RootLayer的部分屬性進(jìn)行修改時(shí)涵叮,默認(rèn)會(huì)自動(dòng)產(chǎn)生一些動(dòng)畫(huà)效果而這些屬性稱為AnimatableProperties(可動(dòng)畫(huà)屬性)
列舉幾個(gè)常見(jiàn)的AnimatableProperties:
bounds:用于設(shè)置CALayer的寬度和高度惭蹂。修改這個(gè)屬性會(huì)產(chǎn)生縮放動(dòng)畫(huà)
backgroundColor:用于設(shè)置CALayer的背景色。修改這個(gè)屬性會(huì)產(chǎn)生背景色的漸變動(dòng)畫(huà)
position:用于設(shè)置CALayer的位置割粮。修改這個(gè)屬性會(huì)產(chǎn)生平移動(dòng)畫(huà)
?
可以通過(guò)動(dòng)畫(huà)事務(wù)(CATransaction)關(guān)閉默認(rèn)的隱式動(dòng)畫(huà)效果
[CATransactionbegin];
[CATransactionsetDisableActions:YES];
self.myview.layer.position= CGPointMake(10, 10);
[CATransactioncommit];
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) CALayer *myLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view.layer addSublayer:self.myLayer];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[CATransaction begin];
[CATransaction setDisableActions:YES];
// 關(guān)閉隱式動(dòng)畫(huà)
self.myLayer.anchorPoint = CGPointMake(0, 0);
// 執(zhí)行動(dòng)畫(huà)事務(wù)
[CATransaction commit];
}
-(CALayer *)myLayer{
if (_myLayer ==nil) {
_myLayer = [CALayer layer];
_myLayer.frame = CGRectMake(100, 100, 100, 100);
_myLayer.backgroundColor = [UIColor redColor].CGColor;
self.myLayer = _myLayer;
}
return _myLayer;
}
@end
效果圖