原文鏈接:http://blog.csdn.net/mumubumaopao/article/details/52005730
之前在項(xiàng)目中,經(jīng)常會需要設(shè)置圓角的一些屬性或者一些動畫,經(jīng)常會涉及到layer層的東西,而如果需要我們自定義圖形的話,那么我們經(jīng)常就會用到CAShapeLayer來創(chuàng)建了.而且經(jīng)常與其一起搭配使用的是UIBezierPath.這兩天比較閑,就寫了這篇博客來記錄下自己寫的一個(gè)小Demo,雖然使用起來很簡單,但是偶爾想不起來如何設(shè)置的話,也是一件很糾結(jié)的事情…
如果我們要繪制一個(gè)幾何圖形的話,我們可以使用簡單的UIBezierPath來繪制,但是這樣的話就必須在UIView的drawRect方法里來繪制或者調(diào)用,但是drawRect:方法不能手動顯示調(diào)用,必須通過調(diào)用setNeedsDisplay或者setNeedsDisplayInRect拱绑,讓系統(tǒng)自動調(diào)該方法,如果我們需要即時(shí)的繪圖的話,這對我們來說難免是一個(gè)約束,但是使用CAShapeLayer和UIBezierPath的話,則可以讓我們放開雙手,隨時(shí)隨地的進(jìn)行繪圖.該博客只是示范CAShapeLayer的簡單使用,下一篇博客我會具體說一下UIBezierPath的使用.
Demo效果圖
CAShaperLayer簡介及使用注意
CAShapeLayer是CALayer的子類,但是要比CALayer更加的靈活,也為我們提供了更多樣的設(shè)置元素.使用CAShapeLayer的話,需要使用一個(gè)給定的Path來設(shè)置他的繪圖路線,這個(gè)path就是由UIBezierPath來提供的.
CAShapeLayer在初始化時(shí)也需要給一個(gè)frame值,但是,它本身沒有形狀,它的形狀來源于你給定的一個(gè)path,然后它去取CGPath值,它與CALayer有著很大的區(qū)別廢話不多說,看代碼,代碼很簡單,我有詳細(xì)的注解.看代碼是最好的交流方式.
代碼講解
首先創(chuàng)建創(chuàng)建CALayer對象并且設(shè)置frame,將shapeLayer放在視圖的中心
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = CGRectMake(0, 0, 200, 200);
shapeLayer.position = self.view.center;
使用貝塞爾曲線繪制一個(gè)圓形的路徑,并且將shapeLayer的路徑設(shè)置為繪制好的貝塞爾曲線(圓形)
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0, 0, 200, 200)];
path.lineCapStyle = kCGLineCapRound; //貝塞爾線段端點(diǎn)格式 (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)
path.lineJoinStyle = kCGLineJoinRound; //貝塞爾線段連接點(diǎn)格式
shapeLayer.path = path.CGPath;
設(shè)置填充顏色和背景顏色
shapeLayer.fillColor = [UIColor redColor].CGColor;
shapeLayer.backgroundColor = [UIColor greenColor].CGColor;
設(shè)置邊框?qū)挾群瓦吙蝾伾?這個(gè)地方說的是住背景邊框,并不是我們繪制path
shapeLayer.borderWidth = 4;
shapeLayer.borderColor = [UIColor blueColor].CGColor;
設(shè)置陰影的顏色以及偏移量和透明度,透明度的屬性默認(rèn)是0.0 所以如果我們不設(shè)置透明度的屬性的話,那么將看不到陰影
,需要說明的是,我們添加的這個(gè)陰影暫時(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.在后面我會具體講解這個(gè)概念
shapeLayer.cornerRadius = 13;
shapeLayer.masksToBounds = true;
值得一提的是,當(dāng)我們設(shè)置masksToBounds屬性為true的時(shí)候,圖層屬性的混合體被指定為在未預(yù)合成之前不能直接在屏幕中繪制综芥,所以就需要屏幕外渲染被喚起,這就是我們平常說的離屏渲染.如果說需要渲染的控件不多的話,那么對程序的性能不會咋造成太大的影響,但是如果需要渲染的控件很多的話,比如在tableView里需要渲染很多控件,那么就會導(dǎo)致界面卡頓的現(xiàn)象十分嚴(yán)重.關(guān)于離屏渲染這個(gè)問題,我會在以后的博客中進(jìn)行討論.
設(shè)置路徑寬度(使用貝塞爾曲線繪制的路徑寬度)以及路徑顏色
shapeLayer.lineWidth = 20;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
將主圖層添加到視圖圖層上去并顯示出來
[self.view.layer addSublayer:shapeLayer];
代碼中容易混淆的地方
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切了圓角,這個(gè)操作主要是將超出主視圖顯示區(qū)域的內(nèi)容切除掉,你肯定很奇怪為什么我們添加了圓角但是看不到效果,其實(shí)是因?yàn)槲覀兲砑拥年幱笆浅龈敢晥D范圍的,而且我們又將masksToBounds設(shè)置為true,這就意味著,添加的陰影將會被切除掉,因?yàn)樗浅龈敢晥D范圍的.
如果我們設(shè)置這個(gè)屬性的為false的話,那么超出主視圖范圍的屬性也是可見的,效果如下所示:
同時(shí)我們可以看到,由于設(shè)置的path比較寬(shapeLayer.lineWidth = 20),在我們設(shè)置完maskToBouns屬性之后,超出主視圖的邊線也被切除掉了.
如下所示:
經(jīng)過我的實(shí)驗(yàn),如果我們設(shè)置路徑寬度為20的話,那么當(dāng)繪制的時(shí)候,路徑會向內(nèi)外各延伸10個(gè)單位,然后完成路徑的繪制,比如我們繪制一個(gè)內(nèi)切于正方形的圓,設(shè)置路線寬度為20,那么效果如下所示:
4 . 源碼
想看效果的話可以去gitHub上下載我的工程:https://github.com/TheRuningAnt/TestCAShapeLayer.git
或者自行拷貝代碼,粘貼運(yùn)行,各位看官請便:
CAShapeLayer *shapeLayer = [CAShapeLayer layer];//創(chuàng)建CALayer對象shapeLayer.frame= CGRectMake(0,0,200,200);//設(shè)置frameshapeLayer.position=self.view.center;//將shapeLayer放在視圖的中心UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0,0,200,200)];//使用貝塞爾曲線繪制一個(gè)圓形的路徑path.lineCapStyle= kCGLineCapRound;//貝塞爾線段端點(diǎn)格式? (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)path.lineJoinStyle= kCGLineJoinRound;//貝塞爾線段連接點(diǎn)格式 (該demo暫不做詳細(xì)介紹 請參考我的其他博文有詳細(xì)介紹)shapeLayer.path= path.CGPath;//將shapeLayer的路徑設(shè)置為繪制好的貝塞爾曲線(圓形)shapeLayer.fillColor= [UIColorredColor].CGColor;//設(shè)置填充顏色shapeLayer.backgroundColor= [UIColorgreenColor].CGColor;//設(shè)置背景顏色shapeLayer.borderWidth=4;//設(shè)置邊框?qū)挾萻hapeLayer.borderColor= [UIColorblueColor].CGColor;//設(shè)置邊框顏色shapeLayer.shadowColor= [UIColorgrayColor].CGColor;//設(shè)置陰影顏色shapeLayer.shadowOffset= CGSizeMake(5,15);//設(shè)置陰影偏移量shapeLayer.shadowOpacity=0.6;//設(shè)置陰影的透明度? 默認(rèn)為透明的 0.0shapeLayer.cornerRadius=13;//設(shè)置圓角shapeLayer.masksToBounds=true;//將超出主圖層范圍的內(nèi)容切掉? 在UIView里這一屬性對應(yīng)的方法是clipsToBoundsshapeLayer.lineWidth=20;//設(shè)置路徑寬度(使用貝塞爾曲線繪制的路徑寬度)shapeLayer.strokeColor= [UIColorblackColor].CGColor;//設(shè)置路徑顏色[self.view.layeraddSublayer:shapeLayer];//將主圖層添加到視圖圖層上去并顯示出來
加入審核被拒交流群,一起交流審核上架經(jīng)驗(yàn)吧~~ 群號:689757099