CALayer

1、什么是CALayer?

? ? ? ?在創(chuàng)建UIView對象時,UIView內(nèi)部會自動創(chuàng)建一個層(即CALayer對象),通過UIView的layer屬性可以訪問這個層。當UIView需要顯示到屏幕上時,會調(diào)用drawRect:方法進行繪圖,并且會將所有內(nèi)容繪制在自己的層上,繪圖完畢后,系統(tǒng)會將層拷貝到屏幕上,于是就完成了UIView的顯示。

2、CALayer的簡單使用

? ? ? ? CALayer是被定義在QuartzCore框架中的,因此要想使用CALayer,先導入QuartzCore框架;在項目中導入QuartzCore頭文件。

使用場景:給控件設置陰影、設置圓角大小、設置邊框的顏色和寬度、設置旋轉?

? ? ? ?注意:這里使用UIColor的CGColor屬性。當設置了masksToBounds為YES時,將不再出現(xiàn)陰影效果

? ? ? ?另外:在設置圖片時.jpg格式的圖片在Assets文件之外無法使用imageNamed: 進行賦值

? ? ? UIView內(nèi)部默認有個CALayer對象(層),通過layer屬性可以訪問這個層。但是,這個默認的層不允許重新創(chuàng)建,可以往層里面添加子層。CALayer可以通過addSublayer:方法添加子層

Example :通過UIImageView進行舉例

UIImageView*img = [[UIImageViewalloc]initWithFrame:CGRectMake(100,100,200,200)];

img.image= [UIImageimageNamed:@"girl"];

[self.viewaddSubview:img];

// 1.設置陰影

img.layer.shadowColor= [UIColorgrayColor].CGColor;

img.layer.shadowOffset=CGSizeMake(10,10);

img.layer.shadowOpacity=0.5;

// 2.設置圓角

img.layer.cornerRadius=10;

img.layer.masksToBounds=YES;

// 3.設置邊框

img.layer.borderWidth=8;

img.layer.borderColor= [UIColoryellowColor].CGColor;

// 4.設置旋轉

img.layer.transform=CATransform3DMakeRotation(M_PI_4,0,0,1);

// 添加一個簡單的圖層

CALayer*layer = [CALayerlayer];

// 設置寬度和高度

layer.bounds=CGRectMake(0,0,100,100);

// 設置層的位置

layer.position=CGPointMake(100,400);

// 設置顏色

layer.backgroundColor= [UIColorblueColor].CGColor;

// 設置圓角

layer.cornerRadius=10;

// 設置邊框

layer.borderColor= [UIColorredColor].CGColor;

layer.borderWidth=8;

// 添加到父控件的layer上

[self.view.layeraddSublayer:layer];

// 添加一個現(xiàn)實圖片的圖層

CALayer*myLayer = [CALayerlayer];

myLayer.bounds=CGRectMake(0,0,100,100);

myLayer.position=CGPointMake(300,400);

// 設置需要顯示的圖片 注意:此刻是將圖片添加到contents的屬性上

myLayer.contents= (id)[UIImageimageNamed:@"girl"].CGImage;

myLayer.cornerRadius=10;

myLayer.masksToBounds=YES;

// 添加到父視圖的layer上

[self.view.layeraddSublayer:myLayer];


模擬器顯示效果

3、問題:為什么使用CGColorRef和CGImageRef這兩種數(shù)據(jù)類型?

? ? ? 首先,CALayer是定義在QuartzCore框架中的;CGImageRef、CGColorRef兩種數(shù)據(jù)類型是定義在CoreGraphics框架中的;UIColor、UIImage是定義在UIKit框架中的;其次,QuartzCore框架和CoreGraphics框架是可以跨平臺使用的,在iOS和Mac OS X上都能使用,但是UIKit只能在iOS中使用。因此,為了保證可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef,比如實例中,我們可以通過UIKit對象的特定方法(CGImage),得到CoreGraphics對象

4、UIView和CALayer的區(qū)別:

1> UIView和CALayer最大的區(qū)別在于,UIView比CALayer多了一個處理事件的功能,也就是說CALayer不具備處理用戶觸摸事件的能力。所以可以通過判斷我們顯示的內(nèi)容是否需要和用戶進行交互確定采用何種方式來顯示

2> CALayer的性能會高一些,輕量級

5、隱式動畫屬性

? ? ? 每一個UIView內(nèi)部都默認關聯(lián)著一個CALayer,我們可用稱這個Layer為Root Layer(根層)。所有的非Root Layer,也就是手動創(chuàng)建的CALayer對象,都存在著隱式動畫。

? ? ? 當對非Root Layer的部分屬性進行相應的修改時,默認會自動產(chǎn)生一些動畫效果,這些屬性稱為Animatable Properties(可動畫屬性)。

1> 列舉幾個常見的Animatable Properties:

bounds:用于設置CALayer的寬度和高度。修改這個屬性會產(chǎn)生縮放動畫

backgroundColor:用于設置CALayer的背景色。修改這個屬性會產(chǎn)生背景色的漸變動畫

position:用來設置CALayer在父層中的位置,它是以父層的左上角為坐標原點(0, 0),修改這個屬性會產(chǎn)生平移動畫

anchorPoint:錨點,也稱為"定位點",它決定著CALayer身上的哪個點會在position屬性所指的位置。它的x、y取值范圍都是0~1,默認值為(0.5, 0.5),默認情況下,CALayer的中點會在position所指定的位置上。

6、CALayer自定義層

自定義層,其實就是在層上繪圖

1> 方法描述: 創(chuàng)建一個CALayer的子類,然后覆蓋drawInContext:方法,使用Quartz2D API進行繪圖

第一步:在ZXLayer.h 文件的.m 中

/**

重寫這個方法進行圖形繪制

*/

- (void)drawInContext:(CGContextRef)ctx{

// 設置為藍色

CGContextSetRGBFillColor(ctx,0,0,1,1.0);

CGContextMoveToPoint(ctx,50,0);

// 連到點(0,100)

CGContextAddLineToPoint(ctx,0,100);

// 連到點(100,100)

CGContextAddLineToPoint(ctx,100,100);

// 合并路徑

CGContextClosePath(ctx);

// 繪制路徑

CGContextFillPath(ctx);

}

第二步:在控制器中通過自定義的layer添加圖層

// 通過自定義控件添加圖層

ZXLayer*mLayer = [ZXLayerlayer];

// 設置寬高

mLayer.bounds=CGRectMake(0,0,100,100);

// 設置位置

mLayer.position=CGPointMake(100,100);

// 添加邊框

mLayer.borderColor= [UIColorredColor].CGColor;

mLayer.borderWidth=8;

// 開始繪制圖層 ----- 觸發(fā)drawInContext:方法

[mLayersetNeedsDisplay];

// 添加圖層

[self.view.layeraddSublayer:mLayer];

2> 方法描述:設置CALayer的delegate,然后讓delegate實現(xiàn)drawLayer:inContext:方法,當CALayer需要繪圖時,會調(diào)用delegate的drawLayer:inContext:方法進行繪圖。

注意:不能再將某個UIView設置為CALayer的delegate,因為UIView對象已經(jīng)是它內(nèi)部根層的delegate,再次設置為其他層的delegate就會出問題。UIView和它內(nèi)部CALayer的默認關系圖:

第一步:創(chuàng)建新的層,設置delegate,然后添加到控制器的view的layer中

CALayer*nlayer = [CALayerlayer];

// 設置delegate --- 要遵守協(xié)議 CALayerDelegate

nlayer.delegate=self;

// 設置層的寬高

nlayer.bounds=CGRectMake(0,0,100,100);

// 設置層的位置

nlayer.position=CGPointMake(100,100);

// 開始繪制圖層

[nlayersetNeedsDisplay];

[self.view.layeraddSublayer:nlayer];

第二步:讓CALayer的delegate(前面設置的是控制器)實現(xiàn)drawLayer:inContext:方法

/**

實現(xiàn)代理方法

*/

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx{

// 設置藍色

CGContextSetRGBStrokeColor(ctx,0,0,1,1);

// 設置邊框寬度

CGContextSetLineWidth(ctx,10);

// 添加一個跟層一樣大的矩形到路徑中

CGContextAddRect(ctx, layer.bounds);

// 繪制路徑

CGContextStrokePath(ctx);

}


模擬器顯示效果

7、UIView的詳細顯示過程

? ? ? ?當UIView需要顯示時,它內(nèi)部的層會準備好一個CGContextRef(圖形上下文),然后調(diào)用delegate(這里就是UIView)的drawLayer:inContext:方法,并且傳入已經(jīng)準備好的CGContextRef對象。而UIView在drawLayer:inContext:方法中又會調(diào)用自己的drawRect:方法

? ? ? ?平時在drawRect:中通過UIGraphicsGetCurrentContext()獲取的就是由層傳入的CGContextRef對象,在drawRect:中完成的所有繪圖都會填入層的CGContextRef中,然后被拷貝至屏幕

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復雜,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,141評論 5 13
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復雜,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,566評論 6 30
  • CALayer1-簡介 本文目錄 一、什么是CALayer 二、CALayer的簡單使用 回到頂部 一、什么是CA...
    白水灬煮一切閱讀 2,607評論 0 8
  • 一、CAShapelayer 我們知道可以不使用圖片情況下利用CGpath去構建任意形狀的陰影。其實我們也可...
    小貓仔閱讀 1,515評論 0 5
  • CALayer簡介 在介紹動畫操作之前我們必須先來了解一個動畫中常用的對象CALayer。CALayer包含在Qu...
    Minlay閱讀 2,024評論 3 6