CAShapeLayer的使用

CAShapeLayer的使用

之前在項目中,經(jīng)常會需要設(shè)置圓角的一些屬性或者一些動畫,經(jīng)常會涉及到layer層的東西,而如果需要我們自定義圖形的話,那么我們經(jīng)常就會用到CAShapeLayer來創(chuàng)建了.而且經(jīng)常與其一起搭配使用的是UIBezierPath.這兩天比較閑,就寫了這篇博客來記錄下自己寫的一個小Demo,雖然使用起來很簡單,但是偶爾想不起來如何設(shè)置的話,也是一件很糾結(jié)的事情…

如果我們要繪制一個幾何圖形的話,我們可以使用簡單的UIBezierPath來繪制,但是這樣的話就必須在UIView的drawRect方法里來繪制或者調(diào)用,但是drawRect:方法不能手動顯式調(diào)用,必須通過調(diào)用setNeedsDisplay或者setNeedsDisplayInRect匪蟀,讓系統(tǒng)自動調(diào)該方法,如果我們需要即時的繪圖的話,這對我們來說難免是一個約束,但是使用CAShapeLayer和UIBezierPath的話,則可以讓我們放開雙手,隨時隨地的進(jìn)行繪圖.該博客只是示范CAShapeLayer的簡單使用,下一篇博客我會具體說一下UIBezierPath的使用.

Demo效果圖:

  1. CAShaperLayer簡介及使用注意
    CAShapeLayer是CALayer的子類,但是要比CALayer更加的靈活,也為我們提供了更多樣的設(shè)置元素.使用CAShapeLayer的話,需要使用一個給定的Path來設(shè)置他的繪圖路線,這個path就是由UIBezierPath來提供的.

    CAShapeLayer在初始化時也需要給一個frame值,但是,它本身沒有形狀,它的形狀來源于你給定的一個path,然后它去取CGPath值,它與CALayer有著很大的區(qū)別廢話不多說,看代碼,代碼很簡單,我有詳細(xì)的注解.看代碼是最好的交流方式.

  2. 代碼講解

    • 首先創(chuàng)建創(chuàng)建CALayer對象并且設(shè)置frame,將shapeLayer放在視圖的中心
      CAShapeLayer *shapeLayer = [CAShapeLayer layer];
      shapeLayer.frame = CGRectMake(0, 0, 200, 200);
      shapeLayer.position = self.view.center;

    • 使用貝塞爾曲線繪制一個圓形的路徑,并且將shapeLayer的路徑設(shè)置為繪制好的貝塞爾曲線(圓形)
      UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0, 0, 200, 200)];
      path.lineCapStyle = kCGLineCapRound; //貝塞爾線段端點格式 (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)
      path.lineJoinStyle = kCGLineJoinRound; //貝塞爾線段連接點格式
      shapeLayer.path = path.CGPath;

    • 設(shè)置填充顏色和背景顏色
      shapeLayer.fillColor = [UIColor redColor].CGColor;
      shapeLayer.backgroundColor = [UIColor greenColor].CGColor;

    • 設(shè)置邊框?qū)挾群瓦吙蝾伾?這個地方說的是住背景邊框,并不是我們繪制path
      shapeLayer.borderWidth = 4;
      shapeLayer.borderColor = [UIColor blueColor].CGColor;

    • 設(shè)置陰影的顏色以及偏移量和透明度,透明度的屬性默認(rèn)是0.0 所以如果我們不設(shè)置透明度的屬性的話,那么將看不到陰影
      ,需要說明的是,我們添加的這個陰影暫時是看不到效果的,原因我會在后面講解.
      shapeLayer.shadowColor = [UIColor grayColor].CGColor;
      shapeLayer.shadowOffset = CGSizeMake(5, 15);
      shapeLayer.shadowOpacity = 0.6;

    • 設(shè)置圓角屬性,需要注意的是,cornerRadius設(shè)置的是圓角的值,maskToBounds設(shè)置的是切除超過主視圖范圍的內(nèi)容,在UIView里這一屬性對應(yīng)的方法是clipsToBounds.在后面我會具體講解這個概念
      shapeLayer.cornerRadius = 13;
      shapeLayer.masksToBounds = true;
      值得一提的是,當(dāng)我們設(shè)置masksToBounds屬性為true的時候,圖層屬性的混合體被指定為在未預(yù)合成之前不能直接在屏幕中繪制扣囊,所以就需要屏幕外渲染被喚起,這就是我們平常說的離屏渲染.如果說需要渲染的控件不多的話,那么對程序的性能不會咋造成太大的影響,但是如果需要渲染的控件很多的話,比如在tableView里需要渲染很多控件,那么就會導(dǎo)致界面卡頓的現(xiàn)象十分嚴(yán)重.關(guān)于離屏渲染這個問題,我會在以后的博客中進(jìn)行討論.

    • 設(shè)置路徑寬度(使用貝塞爾曲線繪制的路徑寬度)以及路徑顏色
      shapeLayer.lineWidth = 20;
      shapeLayer.strokeColor = [UIColor blackColor].CGColor;

    • 將主圖層添加到視圖圖層上去并顯示出來
      [self.view.layer addSublayer:shapeLayer];

  3. 代碼中容易混淆的地方

    • shapeLayer.position = self.view.center;
      只有l(wèi)ayer層才有position屬性,UIView有center屬性,我們使用view.layer.position也可以獲取到layer的position.這行代碼的意思是,將自己創(chuàng)建的shapeLayer放在父視圖的中央位置.
    • 我們使用shapeLayer.masksToBounds對我們創(chuàng)建的shapeLayer切了圓角,這個操作主要是將超出主視圖顯示區(qū)域的內(nèi)容切除掉,你肯定很奇怪為什么我們添加了圓角但是看不到效果,其實是因為我們添加的陰影是超出父視圖范圍的,而且我們又將masksToBounds設(shè)置為true,這就意味著,添加的陰影將會被切除掉,因為它是超出父視圖范圍的.

    如果我們設(shè)置這個屬性的為false的話,那么超出主視圖范圍的屬性也是可見的,效果如下所示:

同時我們可以看到,由于設(shè)置的path比較寬(shapeLayer.lineWidth = 20),在我們設(shè)置完maskToBouns屬性之后,超出主視圖的邊線也被切除掉了.
如下所示:


image

經(jīng)過我的實驗,如果我們設(shè)置路徑寬度為20的話,那么當(dāng)繪制的時候,路徑會向內(nèi)外各延伸10個單位,然后完成路徑的繪制,比如我們繪制一個內(nèi)切于正方形的圓,設(shè)置路線寬度為20,那么效果如下所示:

4 . 源碼

想看效果的話可以去gitHub上下載我的工程:https://github.com/TheRuningAnt/TestCAShapeLayer.git

或者自行拷貝代碼,粘貼運行,各位看官請便:

    CAShapeLayer *shapeLayer = [CAShapeLayer layer];   //創(chuàng)建CALayer對象
    shapeLayer.frame = CGRectMake(0, 0, 200, 200);   //設(shè)置frame
    shapeLayer.position = self.view.center;           //將shapeLayer放在視圖的中心

    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0, 0, 200, 200)]; //使用貝塞爾曲線繪制一個圓形的路徑
    path.lineCapStyle = kCGLineCapRound;    //貝塞爾線段端點格式  (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)
    path.lineJoinStyle = kCGLineJoinRound;  //貝塞爾線段連接點格式 (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)
    shapeLayer.path = path.CGPath;   //將shapeLayer的路徑設(shè)置為繪制好的貝塞爾曲線(圓形)

    shapeLayer.fillColor = [UIColor redColor].CGColor;  //設(shè)置填充顏色
    shapeLayer.backgroundColor = [UIColor greenColor].CGColor;  //設(shè)置背景顏色

    shapeLayer.borderWidth = 4;                          //設(shè)置邊框?qū)挾?    shapeLayer.borderColor = [UIColor blueColor].CGColor; //設(shè)置邊框顏色

    shapeLayer.shadowColor = [UIColor grayColor].CGColor;   //設(shè)置陰影顏色
    shapeLayer.shadowOffset = CGSizeMake(5, 15);             //設(shè)置陰影偏移量
    shapeLayer.shadowOpacity = 0.6;                        //設(shè)置陰影的透明度  默認(rèn)為透明的 0.0

    shapeLayer.cornerRadius = 13;             //設(shè)置圓角
    shapeLayer.masksToBounds = true;          //將超出主圖層范圍的內(nèi)容切掉  在UIView里這一屬性對應(yīng)的方法是clipsToBounds

    shapeLayer.lineWidth = 20;               //設(shè)置路徑寬度(使用貝塞爾曲線繪制的路徑寬度)
    shapeLayer.strokeColor = [UIColor blackColor].CGColor;  //設(shè)置路徑顏色

    [self.view.layer addSublayer:shapeLayer];  //將主圖層添加到視圖圖層上去并顯示出來
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鳍贾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子枯跑,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹬癌,死亡現(xiàn)場離奇詭異,居然都是意外死亡虹茶,警方通過查閱死者的電腦和手機(jī)逝薪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝴罪,“玉大人董济,你說我怎么就攤上這事∫牛” “怎么了虏肾?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長欢搜。 經(jīng)常有香客問我封豪,道長,這世上最難降的妖魔是什么炒瘟? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任撑毛,我火速辦了婚禮,結(jié)果婚禮上唧领,老公的妹妹穿的比我還像新娘。我一直安慰自己雌续,他們只是感情好斩个,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驯杜,像睡著了一般受啥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天滚局,我揣著相機(jī)與錄音居暖,去河邊找鬼。 笑死藤肢,一個胖子當(dāng)著我的面吹牛太闺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘁圈,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼省骂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了最住?” 一聲冷哼從身側(cè)響起钞澳,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涨缚,沒想到半個月后轧粟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡脓魏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年兰吟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轧拄。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡揽祥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出檩电,到底是詐尸還是另有隱情拄丰,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布俐末,位于F島的核電站料按,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卓箫。R本人自食惡果不足惜载矿,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烹卒。 院中可真熱鬧闷盔,春花似錦、人聲如沸旅急。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽藐吮。三九已至溺拱,卻和暖如春逃贝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背迫摔。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工沐扳, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人句占。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓沪摄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辖众。 傳聞我的和親對象是個殘疾皇子卓起,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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