一、概述框架
在iOS中,你能看得見摸得着的東西基本上都是UIView,好比一個按鈕、一個文本標籤、一個文本輸入框、一個圖標等等,這些都是UIView,其實UIView之因此能顯示在屏幕上,徹底是由於它內部的一個圖層,在建立UIView對象時,UIView內部會自動建立一個圖層(即CALayer對象),經過UIView的layer屬性能夠訪問這個層:性能
@property(nonatomic,readonly,retain) CALayer *layer;
當UIView須要顯示到屏幕上時,會調用drawRect:方法進行繪圖,而且會將全部內容繪製在本身的圖層上,繪圖完畢後,系統會將圖層拷貝到屏幕上,因而就完成了UIView的顯示。動畫
換句話說,UIView自己不具有顯示的功能,是它內部的圖層有顯示功能。atom
2、CALayer的屬性code
//寬度和高度: @property CGRect bounds; //位置(默認指中點,具體由anchorPoint決定): @property CGPoint position; //錨點(x,y的範圍都是0-1),決定了position的含義: @property CGPoint anchorPoint; //背景顏色(CGColorRef類型): @property CGColorRef backgroundColor; //形變屬性: @property CATransform3D transform; //邊框顏色(CGColorRef類型): @property CGColorRef borderColor; //邊框寬度: @property CGFloat borderWidth; //圓角半徑: @property CGColorRef borderColor; //內容(好比設置爲圖片CGImageRef): @property(retain) id contents;
例如:orm
//邊框寬度 self.iconView.layer.borderWidth = 10; // 邊框顏色 self.iconView.layer.borderColor = [UIColor greenColor].CGColor; // 圓角 self.iconView.layer.cornerRadius = 10; // 超出主層邊框範圍的內容都剪掉 self.iconView.layer.masksToBounds = YES; // 陰影顏色 self.iconView.layer.shadowColor = [UIColor blueColor].CGColor; // 陰影誤差 self.iconView.layer.shadowOffset = CGSizeMake(20, 20); // 陰影不透明度 self.iconView.layer.shadowOpacity = 0.5;
【備註】新建圖層:對象
CALayer *layer = [[CALayer alloc]init];
或者:
事件
CALayer *layer = [CALayer layer];
例如:圖片
// 新建圖層 //CALayer *layer = [[CALayer alloc] init]; CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.bounds = CGRectMake(0, 0, 100, 100); layer.position = CGPointMake(200, 100); layer.cornerRadius = 10; layer.masksToBounds = YES; layer.contents = (id)[UIImage imageNamed:@"lufy"].CGImage; [self.view.layer addSublayer:layer];
運行結果:事務
3、x\y\z軸
座標原點(0,0,0)
好比使圖層寬度變成1.5倍,高度變成0.5倍:
self.iconView.layer.transform = CATransform3DMakeScale(1.5, 0.5, 0);
繞着(0,0,1)順時針旋轉45度,即繞着Z軸旋轉45度:
self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
上面旋轉等價於:
NSValue *value = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI_4, 0, 0, 1)]; [self.iconView.layer setValue:value forKeyPath:@"transform"];
也等價於:
[self.iconView.layer setValue:@(M_PI_4) forKeyPath: @"transform.rotation"];
四、 關於CALayer的疑惑
首先:
(1)CALayer是定義在QuartzCore框架中的
(2)CGImageRef、CGColorRef兩種數據類型是定義在CoreGraphics框架中的
(1)UIColor、UIImage是定義在UIKit框架中的
其次:
(1)QuartzCore框架和CoreGraphics框架是能夠跨平臺使用的,在iOS和Mac OS X上都能使用
(2)可是UIKit只能在iOS中使用
(3)爲了保證可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef
5、UIView和CALayer的選擇
經過CALayer,就能作出跟UIView同樣的界面效果,既然CALayer和UIView都能實現相同的顯示效果,那究竟該選擇誰好呢?
其實,對比CALayer,UIView多了一個事件處理的功能。也就是說,CALayer不能處理用戶的觸摸事件,而UIView能夠。
因此,若是顯示出來的東西須要跟用戶進行交互的話,用UIView;若是不須要跟用戶進行交互,用UIView或者CALayer均可以。
固然,CALayer的性能會高一些,由於它少了事件處理的功能,更加輕量級。
6、position和anchorPoint
CALayer有2個很是重要的屬性:position和anchorPoint:
@property CGPoint position;
(1)用來設置CALayer在父層中的位置
(2)以父層的左上角爲原點(0, 0)
@property CGPoint anchorPoint;
(1)稱爲「定位點」、「錨點」,控件旋轉動畫圍繞着錨點旋轉
(2)決定着CALayer身上的哪一個點會在position屬性所指的位置,可用來將控件放到指定位置(設置錨點並把錨點放到position位置)
(3)以本身的左上角爲原點(0, 0)
(4)它的x、y取值範圍都是0~1,默認值爲(0.5, 0.5),即默認是重點
例如:
CALayer *layer = [CALayer layer]; layer.bounds = CGRectMake(0, 0, 100, 100); layer.backgroundColor = [UIColor redColor].CGColor; layer.position = CGPointZero; layer.anchorPoint = CGPointZero; [self.view.layer addSublayer:layer];
7、隱式動畫
每個UIView內部都默認關聯着一個CALayer,咱們可用稱這個Layer爲Root Layer(根層)。
全部的非Root Layer,也就是手動建立的CALayer對象,都存在着隱式動畫。
什麼是隱式動畫?
當對非Root Layer的部分屬性進行修改時,默認會自動產生一些動畫效果,而這些屬性稱爲Animatable Properties(可動畫屬性)。
幾個常見的Animatable Properties:
(1)bounds:用於設置CALayer的寬度和高度。修改這個屬性會產生縮放動畫
(2)backgroundColor:用於設置CALayer的背景色。修改這個屬性會產生背景色的漸變更畫
(3)position:用於設置CALayer的位置。修改這個屬性會產平生移動畫
能夠經過動畫事務(CATransaction)關閉默認的隱式動畫效果:
[CATransaction begin]; [CATransaction setDisableActions:YES]; self.myview.layer.position = CGPointMake(10, 10); [CATransaction commit];
上述代碼執行將不會再有動畫效果。