CoreAnimation day5

今天來學(xué)習(xí)一些專業(yè)圖層

CAShapeLayer

之前我們學(xué)習(xí)到了不使用圖片的情況下用CGPath去構(gòu)造任意形狀的陰影埃跷。如果我們能用同樣的方式創(chuàng)建相同形狀的圖層就好了。

CAShapeLayer是一個(gè)通過矢量圖形而不是bitmap來繪制的圖層子類富俄。你指定諸如顏色和線寬等屬性犹菱,用CGPath來定義想要繪制的圖形破托,最后CAShapeLayer就自動(dòng)渲染出來了查坪。當(dāng)然寸宏,你也可以用Core Graphics直接向原始的CALyer的內(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è)有寄宿圖的普通圖層一樣變得像素化落午。

創(chuàng)建一個(gè)CGPath

CAShapeLayer可以用來繪制所有能夠通過CGPath來表示的形狀谎懦。這個(gè)形狀不一定要閉合肚豺,圖層路徑也不一定要不可破,事實(shí)上你可以在一個(gè)圖層上繪制好幾個(gè)不同的形狀界拦。你可以控制一些屬性比如lineWith(線寬吸申,用點(diǎn)表示單位),lineCap(線條結(jié)尾的樣子),和lineJoin(線條之間的結(jié)合點(diǎn)的樣子)截碴;但是在圖層層面你只有一次機(jī)會(huì)設(shè)置這些屬性梳侨。如果你想用不同顏色或風(fēng)格來繪制多個(gè)形狀,就不得不為每個(gè)形狀準(zhǔn)備一個(gè)圖層了日丹。

用一個(gè)CAShapeLayer渲染一個(gè)簡單的火柴人走哺。CAShapeLayer屬性是CGPathRef類型,但是我們用UIBezierPath幫助類創(chuàng)建了圖層路徑哲虾,這樣我們就不用考慮人工釋放CGPath了丙躏。

圓角

第二章里面提到了CAShapeLayer為創(chuàng)建圓角視圖提供了一個(gè)方法,就是CALayer的cornerRadius屬性(譯者注:其實(shí)是在第四章提到的)束凑。雖然使用CAShapeLayer類需要更多的工作晒旅,但是它有一個(gè)優(yōu)勢就是可以單獨(dú)指定每個(gè)角。

我們創(chuàng)建圓角舉行其實(shí)就是人工繪制單獨(dú)的直線和弧度汪诉,但是事實(shí)上UIBezierPath有自動(dòng)繪制圓角矩形的構(gòu)造方法废恋,下面這段代碼繪制了一個(gè)有三個(gè)圓角一個(gè)直角的矩形:

我們可以通過這個(gè)圖層路徑繪制一個(gè)既有直角又有圓角的視圖。如果我們想依照此圖形來剪裁視圖內(nèi)容扒寄,我們可以把CAShapeLayer作為視圖的宿主圖層鱼鼓,而不是添加一個(gè)子視圖。

CATextLayer

用戶界面是無法從一個(gè)單獨(dú)的圖片里面構(gòu)建的旗们。一個(gè)設(shè)計(jì)良好的圖標(biāo)能夠很好地表現(xiàn)一個(gè)按鈕或控件的意圖蚓哩,不過你遲早都要需要一個(gè)不錯(cuò)的老式風(fēng)格的文本標(biāo)簽。

如果你想在一個(gè)圖層里面顯示文字上渴,完全可以借助圖層代理直接將字符串使用Core Graphics寫入圖層的內(nèi)容(這就是UILabel的精髓)岸梨。如果越過寄宿于圖層的視圖,直接在圖層上操作稠氮,那其實(shí)相當(dāng)繁瑣曹阔。你要為每一個(gè)顯示文字的圖層創(chuàng)建一個(gè)能像圖層代理一樣工作的類,還要邏輯上判斷哪個(gè)圖層需要顯示哪個(gè)字符串隔披,更別提還要記錄不同的字體赃份,顏色等一系列亂七八糟的東西。

萬幸的是這些都是不必要的奢米,Core Animation提供了一個(gè)CALayer的子類CATextLayer抓韩,它以圖層的形式包含了UILabel幾乎所有的繪制特性,并且額外提供了一些新的特性鬓长。

同樣谒拴,CATextLayer也要比UILabel渲染得快得多。很少有人知道在iOS 6及之前的版本涉波,UILabel其實(shí)是通過WebKit來實(shí)現(xiàn)繪制的英上,這樣就造成了當(dāng)有很多文字的時(shí)候就會(huì)有極大的性能壓力炭序。而CATextLayer使用了Core text,并且渲染得非巢匀眨快惭聂。

如果你自習(xí)看這個(gè)文本,你會(huì)發(fā)現(xiàn)一個(gè)奇怪的地方:這些文本有一些像素化了相恃。這是因?yàn)椴]有以Retina的方式渲染辜纲,第二章提到了這個(gè)contentScale屬性,用來決定圖層內(nèi)容應(yīng)該以怎樣的分辨率來渲染拦耐。contentsScale并不關(guān)心屏幕的拉伸因素而總是默認(rèn)為1.0侨歉。如果我們想以Retina的質(zhì)量來顯示文字,我們就得手動(dòng)地設(shè)置CATextLayer的contentsScale屬性

textLayer.contentsScale = [UIScreen mainScreen].scale;

CATextLayer的font屬性不是一個(gè)UIFont類型揩魂,而是一個(gè)CFTypeRef類型幽邓。這樣可以根據(jù)你的具體需要來決定字體屬性應(yīng)該是用CGFontRef類型還是CTFontRef類型(Core Text字體)。同時(shí)字體大小也是用fontSize屬性單獨(dú)設(shè)置的火脉,因?yàn)镃TFontRef和CGFontRef并不像UIFont一樣包含點(diǎn)大小牵舵。這個(gè)例子會(huì)告訴你如何將UIFont轉(zhuǎn)換成CGFontRef。

另外倦挂,CATextLayer的string屬性并不是你想象的NSString類型畸颅,而是id類型。這樣你既可以用NSString也可以用NSAttributedString來指定文本了(注意方援,NSAttributedString并不是NSString的子類)没炒。屬性化字符串是iOS用來渲染字體風(fēng)格的機(jī)制,它以特定的方式來決定指定范圍內(nèi)的字符串的原始信息犯戏,比如字體送火,顏色,字重先匪,斜體等种吸。

富文本

iOS 6中,Apple給UILabel和其他UIKit文本視圖添加了直接的屬性化字符串的支持呀非,應(yīng)該說這是一個(gè)很方便的特性坚俗。不過事實(shí)上從iOS3.2開始CATextLayer就已經(jīng)支持屬性化字符串了。這樣的話岸裙,如果你想要支持更低版本的iOS系統(tǒng)猖败,CATextLayer無疑是你向界面中增加富文本的好辦法,而且也不用去跟復(fù)雜的Core Text打交道降允,也省了用UIWebView的麻煩恩闻。

讓我們編輯一下示例使用到NSAttributedString(見清單6.3).iOS 6及以上我們可以用新的NSTextAttributeName實(shí)例來設(shè)置我們的字符串屬性,但是練習(xí)的目的是為了演示在iOS 5及以下拟糕,所以我們用了Core Text判呕,也就是說你需要把Core Text framework添加到你的項(xiàng)目中。否則送滞,編譯器是無法識(shí)別屬性常量的侠草。

現(xiàn)在基本不用了。

行距和字距

有必要提一下的是犁嗅,由于繪制的實(shí)現(xiàn)機(jī)制不同(Core Text和WebKit)边涕,用CATextLayer渲染和用UILabel渲染出的文本行距和字距也不是不盡相同的。

二者的差異程度(由使用的字體和字符決定)總的來說挺小褂微,但是如果你想正確的顯示普通便簽和CATextLayer就一定要記住這一點(diǎn)功蜓。

UILabel的替代品

我們已經(jīng)證實(shí)了CATextLayer比UILabel有著更好的性能表現(xiàn),同時(shí)還有額外的布局選項(xiàng)并且在iOS 5上支持富文本宠蚂。但是與一般的標(biāo)簽比較而言會(huì)更加繁瑣一些式撼。如果我們真的在需求一個(gè)UILabel的可用替代品,最好是能夠在Interface Builder上創(chuàng)建我們的標(biāo)簽求厕,而且盡可能地像一般的視圖一樣正常工作著隆。

我們應(yīng)該繼承UILabel,然后添加一個(gè)子圖層CATextLayer并重寫顯示文本的方法呀癣。但是仍然會(huì)有由UILabel的-drawRect:方法創(chuàng)建的空寄宿圖美浦。而且由于CALayer不支持自動(dòng)縮放和自動(dòng)布局,子視圖并不是主動(dòng)跟蹤視圖邊界的大小项栏,所以每次視圖大小被更改浦辨,我們不得不手動(dòng)更新子圖層的邊界。

我們真正想要的是一個(gè)用CATextLayer作為宿主圖層的UILabel子類沼沈,這樣就可以隨著視圖自動(dòng)調(diào)整大小而且也沒有冗余的寄宿圖啦流酬。

就像我們在第一章『圖層樹』討論的一樣,每一個(gè)UIView都是寄宿在一個(gè)CALayer的示例上列另。這個(gè)圖層是由視圖自動(dòng)創(chuàng)建和管理的康吵,那我們可以用別的圖層類型替代它么?一旦被創(chuàng)建访递,我們就無法代替這個(gè)圖層了晦嵌。但是如果我們繼承了UIView,那我們就可以重寫+layerClass方法使得在創(chuàng)建的時(shí)候能返回一個(gè)不同的圖層子類拷姿。UIView會(huì)在初始化的時(shí)候調(diào)用+layerClass方法惭载,然后用它的返回類型來創(chuàng)建宿主圖層。

如果你運(yùn)行代碼响巢,你會(huì)發(fā)現(xiàn)文本并沒有像素化描滔,而我們也沒有設(shè)置contentsScale屬性。把CATextLayer作為宿主圖層的另一好處就是視圖自動(dòng)設(shè)置了contentsScale屬性踪古。

在這個(gè)簡單的例子中含长,我們只是實(shí)現(xiàn)了UILabel的一部分風(fēng)格和布局屬性券腔,不過稍微再改進(jìn)一下我們就可以創(chuàng)建一個(gè)支持UILabel所有功能甚至更多功能的LayerLabel類。

如果你打算支持iOS 6及以上拘泞,基于CATextLayer的標(biāo)簽可能就有有些局限性纷纫。但是總得來說,如果想在app里面充分利用CALayer子類陪腌,用+layerClass來創(chuàng)建基于不同圖層的視圖是一個(gè)簡單可復(fù)用的方法辱魁。

明天學(xué)習(xí)3d圖形和更復(fù)雜的動(dòng)畫變幻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诗鸭,一起剝皮案震驚了整個(gè)濱河市染簇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌强岸,老刑警劉巖锻弓,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蝌箍,居然都是意外死亡弥咪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門十绑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聚至,“玉大人,你說我怎么就攤上這事本橙“夤” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵甚亭,是天一觀的道長贷币。 經(jīng)常有香客問我,道長亏狰,這世上最難降的妖魔是什么役纹? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮暇唾,結(jié)果婚禮上促脉,老公的妹妹穿的比我還像新娘。我一直安慰自己策州,他們只是感情好瘸味,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著够挂,像睡著了一般旁仿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孽糖,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天枯冈,我揣著相機(jī)與錄音毅贮,去河邊找鬼。 笑死尘奏,一個(gè)胖子當(dāng)著我的面吹牛滩褥,可吹牛的內(nèi)容都是我干的浙宜。 我是一名探鬼主播讯沈,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼酪耳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了琢感?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤探熔,失蹤者是張志新(化名)和其女友劉穎驹针,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诀艰,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柬甥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了其垄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苛蒲。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绿满,靈堂內(nèi)的尸體忽然破棺而出臂外,到底是詐尸還是另有隱情,我是刑警寧澤喇颁,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布漏健,位于F島的核電站,受9級特大地震影響橘霎,放射性物質(zhì)發(fā)生泄漏蔫浆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一姐叁、第九天 我趴在偏房一處隱蔽的房頂上張望瓦盛。 院中可真熱鬧,春花似錦外潜、人聲如沸谭溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扮念。三九已至,卻和暖如春碧库,著一層夾襖步出監(jiān)牢的瞬間柜与,已是汗流浹背巧勤。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弄匕,地道東北人颅悉。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像迁匠,于是被迫代替她去往敵國和親剩瓶。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

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