CALayer

我是大自然的搬運工,處女第二篇(筆記篇-轉(zhuǎn)載別人的)
什么是CALayer吕喘?
CALayer(這里簡單地稱其為層)漂辐。
首先要說的是CALayers 是屏幕上的一個具有可見內(nèi)容的矩形區(qū)域显拳,每個UIView都有一個根CALayer括细,
其所有的繪制(視覺效果)都是在這個layer上進行的伪很。

UILabel* lable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 30)];  
lable.text = @"test";  
[self.view addSubview: lable];  
lable.backgroundColor = [UIColor clearColor];  
[lable release];  
// 設定CALayer  
self.view.layer.backgroundColor =[UIColor orangeColor].CGColor;  
self.view.layer.cornerRadius =20.0;  
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);  

請注意,我創(chuàng)建的UILable始終隨著UIView的根CALayer的縮放而改變位置奋单。)
其次锉试,CALayer的可以影響其外觀的特性有:層的大小尺寸背景色內(nèi)容(比如圖像或是使用Core Graphics 繪制的內(nèi)容)是否使用圓角是否使用陰影等等.需要說明的是CALayer的大部分屬性都可以用來實現(xiàn)動畫效果。
另外览濒,你可以直接使用CALayer呆盖,也可以使用其子類,如CAGradientLayer贷笛,CATextLayer应又, CAShapeLayer等等。
1乏苦、示例
首先在Xcode中創(chuàng)建一個View-based App株扛,CALayer是屬于QuartzCore framework的,所以需要引入QuartzCore framework汇荐,另外在程序中包括QuartzCore.h洞就。
第一個例子是創(chuàng)建一個帶圓角的層,在你的ViewController中的ViewDidLoad中加入下面代碼:

// Import QuartzCore.h at the top of the file  
#import   
// Uncomment viewDidLoad and add the following lines  
self.view.layer.backgroundColor =[UIColor orangeColor].CGColor;  
self.view.layer.cornerRadius =20.0;  
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);  

然后添加一個帶陰影效果的子層掀淘,加入下列代碼:

CALayer *sublayer = [CALayer layer];  
sublayer.backgroundColor = [UIColor blueColor].CGColor;  
sublayer.shadowOffset = CGSizeMake(0, 3);  
sublayer.shadowRadius = 5.0;  
sublayer.shadowColor = [UIColor blackColor].CGColor;  
sublayer.shadowOpacity = 0.8;  
sublayer.frame = CGRectMake(30, 30, 128, 192);  
[self.view.layer addSublayer:sublayer];  
//為子層增加內(nèi)容(圖片)旬蟋,你還可以設置層的邊框,代碼如下:  
sublayer.contents =(id)[UIImage imageNamed:@"BattleMapSplashScreen.png"].CGImage;  
sublayer.borderColor =[UIColor blackColor].CGColor;  
sublayer.borderWidth =2.0;  

如 果你希望子層也是圓角怎么辦革娄?你可能說很容易設置cornerRadius屬性就行倾贰。實際上你即算是設置了cornerRadius屬性,圖片仍然不會顯 示圓角拦惋。你還需要設置masksToBounds為YES躁染。但是這樣做還是不夠的,因為如果是這樣架忌,這個層的陰影顯示就沒有了吞彤。簡單的實現(xiàn)方法如下(通過 兩個層來實現(xiàn)):

CALayer *sublayer =[CALayer layer];  
sublayer.backgroundColor =[UIColor blueColor].CGColor;  
sublayer.shadowOffset = CGSizeMake(0, 3);  
sublayer.shadowRadius =5.0;  
sublayer.shadowColor =[UIColor blackColor].CGColor;  
sublayer.shadowOpacity =0.8;  
sublayer.frame = CGRectMake(30, 30, 128, 192);  
sublayer.borderColor =[UIColor blackColor].CGColor;  
sublayer.borderWidth =2.0;  
sublayer.cornerRadius =10.0;  
[self.view.layer addSublayer:sublayer];  
CALayer *imageLayer =[CALayer layer];  
imageLayer.frame = sublayer.bounds;  
imageLayer.cornerRadius =10.0;  
imageLayer.contents =(id)[UIImage imageNamed:@"BattleMapSplashScreen.png"].CGImage;  
imageLayer.masksToBounds =YES;  
[sublayer addSublayer:imageLayer];  

最 后,還介紹一下自繪圖型的實現(xiàn)叹放,其要點是要設置所繪制層的delegate饰恕。比如在我們的例子中使用ViewController作為delegate, 那么就需要在ViewController中實現(xiàn)drawLayer:inContext方法井仰,對層進行繪制工作埋嵌。另外,還需要調(diào)用 setNeedsDisplay俱恶,來通知層需要進行繪制了雹嗦,于是層才會通過對delegate的drawLayer:inContext方法進行調(diào)用范舀。
代碼如下:

void MyDrawColoredPattern (void*info, CGContextRef context){  
   
    CGColorRef dotColor =[UIColor colorWithHue:0 saturation:0 brightness:0.07 alpha:1.0].CGColor;  
    CGColorRef shadowColor =[UIColor colorWithRed:1 green:1 blue:1 alpha:0.1].CGColor;  
   
    CGContextSetFillColorWithColor(context, dotColor);  
    CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 1, shadowColor);  
   
    CGContextAddArc(context, 3, 3, 4, 0, radians(360), 0);  
    CGContextFillPath(context);  
   
    CGContextAddArc(context, 16, 16, 4, 0, radians(360), 0);  
    CGContextFillPath(context);  
   
}  
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {  
   
    CGColorRef bgColor =[UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;  
    CGContextSetFillColorWithColor(context, bgColor);  
    CGContextFillRect(context, layer.bounds);  
   
    staticc*****t CGPatternCallbacks callbacks ={0, &MyDrawColoredPattern, NULL};  
   
    CGContextSaveGState(context);  
    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);  
    CGContextSetFillColorSpace(context, patternSpace);  
//還需要注意,radians是一個自定義函數(shù): 
static inline double radians (double degrees) { return degrees * M_PI/180; } 

_______________________________________CALayer_______________________________________
1了罪、CALayer 這個類么锭环,和UIView有什么區(qū)別和聯(lián)系?Layer到底是個什么東西泊藕?
答:就是層啊辅辩,這個層你隨便控制他的大小,旋轉(zhuǎn)娃圆,角度玫锋,坐標變化或者內(nèi)容之類的信息,這些變化還可以通過動畫表現(xiàn)出來讼呢。
UIView所有你能看到的顯示的內(nèi)容撩鹿,后面都有一個Layer。
UIView 的animation我覺得是一種簡化悦屏,實質(zhì)還是調(diào)用的 CALayer 三痰。
每個層都可以設定單獨的動作,還可以給上一級的層設置動作窜管,下一級的層就可以跟著上一層進行動作。
CALayer是為更好實現(xiàn)View的動畫稚机,比如你想View消失時做成玻璃破碎的效果幕帆,
就可以在View的CALayer上密密麻麻排一層N個小的子CALayer, 設置每個CALayer的落下動畫赖条,用View就比較不合適失乾。
一個UIView包含CALayer樹,CALayer是一個數(shù)據(jù)模型纬乍,包含了一些用于顯示的對象碱茁,但本身不用于顯示。

2仿贬、CALayer和UIView的關系?
一個UIView包含CALayer樹纽竣,CALayer是一個數(shù)據(jù)模型,包含了一些用于顯示的對象茧泪,但本身不用于顯示蜓氨。
CALayer相當于photoshop的一個層,很多動畫可以通過設置CALayer來實現(xiàn)队伟。據(jù)說有人用CALayer顯示圖片來播放視頻穴吹。
Core animation應該是用CAlayer來實現(xiàn)各種動畫。

3嗜侮、UIView 與CALayer的區(qū)別?

  1. UIView是iOS系統(tǒng)中界面元素的基礎港令, 所有的界面元素都繼承自它啥容。它本身完全是由CoreAnimation來實 現(xiàn)的(Mac下似乎不是這樣)。它真正的繪圖部分顷霹,是由一個叫CALayer(Core Animation Layer)的類來管理咪惠。UIView本身,更像是一個CALayer的管理器泼返,訪問它的跟繪圖和跟坐標有關的屬性硝逢,例如frame,bounds等等绅喉,實際上內(nèi)部都是在訪問它所包含的CALayer的相關屬性渠鸽。
    2.UIView有個layer屬性,可以返回它的主CALayer實例柴罐,UIView有一個layerClass方法徽缚,返回主layer所使用的類,UIView的子類革屠,可以通過重載這個方法凿试,來讓UIView使用不同的CALayer來顯示,例如通過
- (class) layerClass { 
    return ([CAEAGLLayer class]); 
} 

使某個UIView的子類使用GL來進行繪制似芝。
3.UIView的CALayer類似UIView的子View樹形結(jié)構(gòu)那婉,也可以向它的layer上添加子layer,來完成某些特殊的表示党瓮。例如下面的代碼

grayCover = [[CALayer alloc] init]; 
grayCover.backgroundColor = [[[UIColor blackColor] colorWithAlphaComponent:0.2] CGColor]; 
[self.layer addSubLayer: grayCover]; 

會在目標View上敷上一層黑色的透明薄膜详炬。
4.UIView的layer樹形在系統(tǒng)內(nèi)部,被系統(tǒng)維護著三份copy(這段理解有點吃不準)寞奸。
第一份呛谜,邏輯樹,就是代碼里可以操縱的枪萄,例如更改layer的屬性等等就在這一份隐岛。
第二份,動畫樹瓷翻,這是一個中間層聚凹,系統(tǒng)正在這一層上更改屬性,進行各種渲染操作齐帚。
第三份元践,顯示樹,這棵樹的內(nèi)容是當前正被顯示在屏幕上的內(nèi)容童谒。
這三棵樹的邏輯結(jié)構(gòu)都是一樣的单旁,區(qū)別只有各自的屬性。
5.動畫的運作
UIView的主layer以外(我覺得是這樣)饥伊,對它的subLayer象浑,也就是子layer的屬性進行更改蔫饰,系統(tǒng)將自動進行動畫生成,動畫持續(xù)時間有 個缺省時間愉豺,個人感覺大概是0.5秒篓吁。在動畫時間里,系統(tǒng)自動判定哪些屬性更改了蚪拦,自動對更改的屬性進行動畫插值杖剪,生成中間幀然后連續(xù)顯示產(chǎn)生動畫效果。
6.坐標系系統(tǒng)(對position和anchorPoint的關系還是犯暈)
CALayer的坐標系系統(tǒng)和UIView有點不一樣驰贷,它多了一個叫anchorPoint的屬性盛嘿,它使用CGPoint結(jié)構(gòu),但是值域是0~1括袒,也就是 按照比例來設置次兆。這個點是各種圖形變換的坐標原點,同時會更改layer的position的位置锹锰,它的缺省值是{0.5, 0.5}芥炭,也就是在layer的中央。
某layer.anchorPoint = CGPointMake(0.f, 0.f);
如果這么設置恃慧,layer的左上角就會被挪到原來的中間的位置园蝠,
加上這樣一句就好了
某layer.position = CGPointMake(0.f, 0.f);
7.真實例子的分析
這是iphone上iBook翻頁的效果,假設每一頁都是一個UIView痢士,我覺得一個頁面是貼了倆個Layer彪薛,文字Layer顯示正面的內(nèi)容,背面 layer用文字layer的快照做affine翻轉(zhuǎn)良瞧,貼在文字layer的后面。因為Layer可以設置顯示陰影训唱,也許后面的陰影效果沒有使用單獨的一 個layer來顯示褥蚯。至于這個曲面效果,我查了很多資料也沒有結(jié)果况增,估計是使用了GL的曲面繪圖赞庶?
8.最后一個
layer可以設置圓角顯示,例如UIButton的效果澳骤,也可以設置陰影顯示歧强,但是如果layer樹中的某個layer設置了圓角,樹中所有l(wèi)ayer 的陰影效果都將顯示不了了为肮。如果既想有圓角又想要陰影摊册,好像只能做兩個重疊的UIView,一個的layer顯示圓角颊艳,一個的layer顯示陰 影.....

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茅特,一起剝皮案震驚了整個濱河市忘分,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌白修,老刑警劉巖妒峦,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兵睛,居然都是意外死亡肯骇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門祖很,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笛丙,“玉大人,你說我怎么就攤上這事突琳∪粽” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵拆融,是天一觀的道長蠢琳。 經(jīng)常有香客問我,道長镜豹,這世上最難降的妖魔是什么傲须? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮趟脂,結(jié)果婚禮上泰讽,老公的妹妹穿的比我還像新娘。我一直安慰自己昔期,他們只是感情好已卸,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硼一,像睡著了一般累澡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上般贼,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天愧哟,我揣著相機與錄音,去河邊找鬼哼蛆。 笑死蕊梧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的腮介。 我是一名探鬼主播肥矢,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼叠洗!你這毒婦竟也來了橄抹?” 一聲冷哼從身側(cè)響起靴迫,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎楼誓,沒想到半個月后玉锌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡疟羹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年主守,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榄融。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡参淫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愧杯,到底是詐尸還是另有隱情涎才,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布力九,位于F島的核電站耍铜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏跌前。R本人自食惡果不足惜棕兼,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抵乓。 院中可真熱鬧伴挚,春花似錦、人聲如沸灾炭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜈出。三九已至田弥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掏缎,已是汗流浹背皱蹦。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工煤杀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眷蜈,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓沈自,卻偏偏與公主長得像酌儒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子枯途,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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

  • 在iOS中隨處都可以看到絢麗的動畫效果忌怎,實現(xiàn)這些動畫的過程并不復雜籍滴,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,490評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果榴啸,實現(xiàn)這些動畫的過程并不復雜孽惰,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,111評論 5 13
  • CALayer1-簡介 本文目錄 一鸥印、什么是CALayer 二勋功、CALayer的簡單使用 回到頂部 一、什么是CA...
    白水灬煮一切閱讀 2,590評論 0 8
  • 前言 前面發(fā)了一篇iOS 面試的文章库说,在說到 UIView 和 CALayer 的區(qū)別和聯(lián)系的時候狂鞋,被喵神指出沒有...
    Mz楓閱讀 758評論 0 4
  • CALayer - 在iOS中,你能看得見摸得著的東西基本上都是UIView潜的,比如一個按鈕骚揍、一個文本標簽、一個文本...
    Hevin_Chen閱讀 1,140評論 0 10