6.1 CAShapeLayer
CAShapeLayer是一個(gè)通過矢量圖形而不是bitmap來繪制的圖層子類科雳。指定諸如顏色和線寬等屬性骡男,用CGPath來定義想要繪制的圖形判导,最后CAShapeLayer就自動(dòng)渲染出來了稽亏。當(dāng)然疙筹,你也可以用Core Graphics直接向原始的CALayer的內(nèi)容中繪制一個(gè)路徑富俄,相比之下,使用CAShapeLayer有以下一些優(yōu)點(diǎn):
. 渲染快速而咆。CAShapeLayer使用了硬件加速霍比,繪制同一圖形會(huì)比用Core Graphics快很多。
. 高效使用內(nèi)存暴备。一個(gè)CAShapeLayer不需要像普通CALayer一樣創(chuàng)建一個(gè)寄宿圖形悠瞬,所以無論有多大,都不會(huì)占用太多的內(nèi)存涯捻。
. 不會(huì)被圖層邊界剪裁掉浅妆。一個(gè)CAShapeLayer可以在邊界之外繪制,你的圖層路徑不會(huì)像在使用Core Graphics的普通CALayer一樣被剪裁掉障癌。
. 不會(huì)出現(xiàn)像素化凌外。當(dāng)你給CAShapeLayer做3D變換時(shí),它不像一個(gè)有寄宿圖的普通圖層一樣變得像素化涛浙。
6.1.1 創(chuàng)建一個(gè)CGPath
CAShapeLayer可以用來繪制所有能夠通過CGPath來表示的形狀康辑。這個(gè)形狀不一定要閉合,圖層路徑也不一定要不可破轿亮,事實(shí)上你可以在一個(gè)圖層上繪制好幾個(gè)不同的形狀疮薇。你可以控制一些屬性比如lineWidth(線寬,用點(diǎn)表示單位)我注,lineCap(線條結(jié)尾的樣式),lineJoin(線條之間的結(jié)合點(diǎn)的樣子)惦辛;但是在圖層層面你只有一次機(jī)會(huì)設(shè)置這些屬性。如果你想用不同顏色或風(fēng)格來繪制多個(gè)形狀仓手,就不得不每個(gè)形狀準(zhǔn)備一個(gè)圖層了胖齐。
6.1.2 圓角
通過使用CAShapeLayer創(chuàng)建圓角有一個(gè)優(yōu)勢(shì)就是可以單獨(dú)制定每個(gè)角的形狀
我們創(chuàng)建圓角矩形其實(shí)就是人工繪制單獨(dú)的直線和弧度,但是事實(shí)上UIBezierPath有自動(dòng)繪制圓角矩形的構(gòu)造方法嗽冒。
如果我們可以通過這個(gè)圖層路徑繪制一個(gè)既有直角又有圓角的視圖呀伙。如果我們想依照此圖形來剪裁視圖內(nèi)容,我們可以把CAShapeLayer作為視圖的宿主圖層(即設(shè)置為圖層的mask屬性)添坊,而不是添加一個(gè)子圖層(圖層蒙版的詳細(xì)解釋見第四章中的“視角效果”);
6.2 CATextLayer
6.2.1 CATextLayer
Core Animation提供了一個(gè)CALayer的子類CATextLayer剿另,它以圖層的姓氏包含了UILabel幾乎所有的繪制特性,并且額外提供了一些新的特性。
CATextLayer要比UILabel渲染快得多雨女。在ios6以及之前的版本谚攒,UILabel其實(shí)是通過WebKit來實(shí)現(xiàn)繪制的,這樣就造成了當(dāng)有很多文字的時(shí)候就會(huì)有極大的性能壓力氛堕,而CATextLayer使用了Core Text馏臭,性能消耗小,并且渲染得非乘现桑快括儒。
若CATextLayer未設(shè)置contentsScale屬性,有可能會(huì)出現(xiàn)文本像素化的問題锐想,因?yàn)樗]有以Retina的方式渲染帮寻,contentsScale并不關(guān)心屏幕的拉伸因素默認(rèn)值為1.0。所以赠摇,我們?cè)赗eatina屏幕上顯示文字的時(shí)候固逗,需要手動(dòng)設(shè)置CATextLayer的contentsScale屬性,如下
textLayer.contentsScale = [UIScreen mainScreen].scale;
CATextLayer的font屬性不是一個(gè)UIFont類型藕帜,而是一個(gè)CFTypeRef類型烫罩,這樣可以根據(jù)你的具體需要來決定字體屬性應(yīng)該用CGFontRef類型還是CGFontRef類型(Core Text字體)。同時(shí)字體大小是用fontSize屬性單獨(dú)設(shè)置的耘戚,因?yàn)镃GFontRef和CGFontRef并不像UIFont一樣包含點(diǎn)大小嗡髓。
另外操漠,CATextLayer的string屬性并不是NSString類型收津,而是id類型。這樣你既可以用NSString也可以用NSAttributedString來指定文本了(注意浊伙,NSAttributedString并不是NSString的子類)撞秋。屬性花字符串是ios用來渲染字體風(fēng)格的機(jī)制,它以特定的方式來決定指定范圍內(nèi)的字符串的原始信息嚣鄙,比如字體吻贿、顏色、字重哑子、斜體等舅列。
6.2.2 富文本
ios6開始,Apple給UILabel和其它UIKit文本視圖添加了直接的屬性花字符串的支持卧蜓,應(yīng)該說這是一個(gè)很方便的特性帐要。但在這之前,ios3.2開始弥奸,CATextLayer就已經(jīng)支持屬性化字符串了榨惠,這樣的話,如果你想要支持更低版本的ios系統(tǒng),CATextLayer無疑是你向界面中增加富文本的好辦法赠橙,而且也不用去跟負(fù)責(zé)的Core Text打交道耽装,也省了用UIWebview的麻煩。
Demo中為了掩飾ios5及以下版本期揪,使用的是Core Text掉奄,所以需要把Core Text framework添加到項(xiàng)目中。
6.2.3 行距和字距
由于繪制的實(shí)現(xiàn)機(jī)制不同(Core Text和WebKit),用CATextLayer渲染和用UILabel渲染出的文本行距和字距也是不盡相同的横侦。
二者的差異程度(由使用的字體和字符決定)總體來說挺小挥萌,但是如果你想正確的顯示普通便簽和CATextLayer就一定要記住這一點(diǎn)
6.2.4 UILabel的替代品
由于CATextLayer有著比UILabel更好的性能表現(xiàn),我們可以使用CATextLayer作為UILabel的替代品枉侧,具體步驟如下:
(1).繼承于UILabel引瀑,并且實(shí)現(xiàn)awakeFromNib方法,這樣就可以使用Interface Builder創(chuàng)建榨馁;
(2).重寫+layerClass方法憨栽,返回一個(gè)CATextLayer類型的宿主圖層。
(3).重寫UILable中的各種屬性翼虫,將它們賦值給CATextLayer屑柔。
如demo中所示,我們的文本并沒有像素化珍剑,這是因?yàn)镃ATextLayer作為宿主圖層自動(dòng)設(shè)置了contentsScale屬性掸宛。