1. ? ?CALayer和UIView之間的關(guān)系:
?在iOS系統(tǒng)中福荸,你能看得見摸得著的東西基本上都是UIView,比如UI控件、圖標等等姓迅,都是UIView。
?其實UIView之所以能顯示在屏幕上,完全是因為它內(nèi)部的一個層(CALayer)丁存。
?在創(chuàng)建UIView對象時肩杈,UIView內(nèi)部會自動創(chuàng)建一個層(即CALayer對象),通過UIView的layer屬性可以訪問這個層解寝。當UIView需要顯示到屏幕上時扩然,會調(diào)用drawRect:方法進行繪圖,并且會將所有內(nèi)容繪制在自己的層上聋伦,繪圖完畢后夫偶,系統(tǒng)會將層拷貝到屏幕上,于是就完成了UIView的顯示觉增。
?換句話說兵拢,UIView本身不具備顯示的功能,是它內(nèi)部的層才有顯示功能逾礁。
UIView之所以能夠顯示说铃,完全是因為內(nèi)部的CALayer對象。因此嘹履,通過操作這個CALayer對象截汪,可以很方便地調(diào)整UIView的一些界面屬性,比如:陰影植捎、圓角大小衙解、邊框?qū)挾群皖伾取?/b>
UIView相對于CALayer來說就是多一個事件處理的功能,CALayer是不能處理用戶的觸摸事件焰枢。故如果顯示出來的東西需要跟用戶進行交互的話蚓峦,用UIView;如果不需要跟用戶進行交互济锄,用UIView或者CALayer都可以暑椰。
2.為什么CALayer中使用CGColorRef和CGImageRef這2種數(shù)據(jù)類型,而不用UIColor和UIImage荐绝?
* 首先要知道:CALayer是定義在QuartzCore框架中的一汽;CGImageRef、CGColorRef兩種數(shù)據(jù)類型是定義在CoreGraphics框架中的低滩;UIColor召夹、UIImage是定義在UIKit框架中的
* 其次,QuartzCore框架和CoreGraphics框架是可以跨平臺使用的恕沫,在iOS和Mac OS X上都能使用监憎,但是UIKit只能在iOS中使用
* 因此,為了保證可移植性婶溯,QuartzCore不能使用UIImage鲸阔、UIColor偷霉,只能使用CGImageRef、CGColorRef
* 不過很多情況下褐筛,可以通過UIKit對象的特定方法类少,得到CoreGraphics對象,比如UIImage的CGImage方法可以返回一個CGImageRef
3.UIView的顯示過程
?1. ? 當UIView需要顯示時渔扎,它內(nèi)部的層會準備好一個CGContextRef(圖形上下文)瞒滴,然后調(diào)用delegate(這里就是UIView)的drawLayer:inContext:方法,并且傳入已經(jīng)準備好的CGContextRef對象赞警。而UIView在drawLayer:inContext:方法中又會調(diào)用自己的drawRect:方法
? ?2. ?在drawRect:中通過UIGraphicsGetCurrentContext()獲取的就是由層傳入的CGContextRef對象妓忍,在drawRect:中完成的所有繪圖都會填入層的CGContextRef中,然后被拷貝至屏幕
(1).新建一個繼承于CALayer的類AACALayer愧旦,然后覆蓋drawInContext:方法世剖,在里面繪圖
-(void)drawInContext:(CGContextRef)abc{
?? ? CGContextSetRGBFillColor(abc,0, 1, 0.5, 1);//填充,出現(xiàn)實心
??//? ? 起點
?? ? CGContextMoveToPoint(abc,50, 0);
? // 從(50, 0)連線到(0, 100)
?? ? CGContextAddLines(abc,0, 100);
?// 從(0, 100)連線到(100, 100)
? ? CGContextAddLineToPoint(abc,100, 100);
?//? ? 繪制路徑
?? ? CGContextClosePath(abc);
?? }
(2).不想寫子類笤虫,也可以直接使用代理可以新建層旁瘫,drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx中繪圖,但是不能將UIView設(shè)置為它的代理琼蚯,否則和UIView內(nèi)部就沖突了酬凳,因為UIView已經(jīng)是內(nèi)部根圖層的degegate了。
-(void)viewDidLoad{
? ? CALayer *layerr = [CALayer layer];
?? ? // 設(shè)置層的寬高
?? layerr.bounds = CGRectMake(0, 0, 100, 100);
?? // 設(shè)置層的位置
?? layerr.position = CGPointMake(100, 100);
?? laere.delegate - self;
?? // 開始繪制圖層
?? [layer setNeedsDisplay];//無論采取哪種方法來自定義層遭庶,都必須調(diào)用CALayer的setNeedsDisplay方法才能正常繪圖宁仔。
? ? [self.view.layer addSublayer:layer];
?? }
//在代理方法中
?- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
? ? ? CGContextSetRGBStrokeColor(ctx,0, 0, 1, 1);//這不填充,空心
?? ? CGContextSetLineWidth(ctx,5);
?? ? CGContextAddRect(ctx, layer.bounds);
?? ? CGContextStrokePath(ctx);
}