CAShapeLayer使用

一、CAShapeLayer簡介

CAShapeLayer屬于QuartzCore框架,繼承自CALayer。CAShapeLayer是在坐標系內繪制貝塞爾曲線的,通過繪制貝塞爾曲線,設置shape(形狀)的path(路徑),從而繪制各種各樣的圖形以及不規則圖形。因此,使用CAShapeLayer需要與UIBezierPath一起使用。

UIBezierPath類允許你在自定義的 View 中繪制和渲染由直線和曲線組成的路徑.。你可以在初始化的時候直接為你的UIBezierPath指定一個幾何圖形。

通俗點就是UIBezierPath用來指定繪制圖形路徑,而CAShapeLayer就是根據路徑來繪圖的。

二、CAShapeLayer屬性介紹

1、[CAShapeLayer layer].path

path

@property(nullable)CGPathRefpath;

官方的解釋是定義要呈現的形狀的路徑。如果路徑擴展到層邊界之外,只有當正常層屏蔽規則導致該條線時,它才會自動被剪輯到該層。賦值時,路徑被復制。默認為null。(注意,雖然路徑屬性的動畫,不隱將動畫時創建的屬性發生了變化。)

2、[CAShapeLayer layer].fillColor

fillColor

@property(nullable)CGColorReffillColor;

官方解釋是填充路徑的顏色,或不需要填充。默認顏色為不透明的黑色。

3、[CAShapeLayer layer].fillRule

fillRule

@property(copy)NSString*fillRule;

官方解釋是當在填充顏色的時候則就需要這種填充規則,值有兩種,非零和奇偶數,但默認是非零值。

4、[CAShapeLayer layer].strokeColor

strokeColor

@property(nullable)CGColorRefstrokeColor;

官方解釋是設置描邊色,默認無色。

5、[CAShapeLayer layer].strokeStart與[CAShapeLayer layer].strokeEnd

strokeStart與strokeEnd

@propertyCGFloatstrokeStart;@propertyCGFloatstrokeEnd;

官方解釋是這兩個值被定義用于繪制邊線輪廓路徑的子區域。該值必須在[0,1]范圍,0代表路徑的開始,1代表路徑的結束。在0和1之間的值沿路徑長度進行線性插值。strokestart默認為0,strokeend默認為1。

6、[CAShapeLayer layer]. lineWidth與[CAShapeLayer layer].miterLimit

lineWidth與miterLimit

@propertyCGFloatlineWidth;@propertyCGFloatmiterLimit;

官方解釋是lineWidth為線的寬度,默認為1;miterLimit為最大斜接長度。斜接長度指的是在兩條線交匯處和外交之間的距離。只有lineJoin屬性為kCALineJoinMiter時miterLimit才有效。邊角的角度越小,斜接長度就會越大。為了避免斜接長度過長,我們可以使用miterLimit屬性。如果斜接長度超過miterLimit的值,邊角會以lineJoin的“bevel”即kCALineJoinBevel類型來顯示。

7、[CAShapeLayer layer]. lineCap與[CAShapeLayer layer].lineJoin

lineCap與lineJoin

@property(copy)NSString*lineCap;@property(copy)NSString*lineJoin;

lineCap為線端點類型,值有三個類型,分別為kCALineCapButt 、kCALineCapRound 、kCALineCapSquare,默認值為Butt;lineJoin為線連接類型,其值也有三個類型,分別為kCALineJoinMiter、kCALineJoinRound、kCALineJoinBevel,默認值是Miter。

8、[CAShapeLayer layer]. lineDashPhase與[CAShapeLayer layer]. lineDashPattern

lineDashPhase與lineDashPattern

@propertyCGFloatlineDashPhase;@property(nullable,copy)NSArray *lineDashPattern;

官方解釋是lineDashPhase為線型模版的起始位置;lineDashPattern為線性模版,這是一個NSNumber的數組,索引從1開始記,奇數位數值表示實線長度,偶數位數值表示空白長度。

注:fillColor與strokeColor都是在有UIBezierPath參數配置的情況下才能發生作用

三、開始繪制

1、顏色說明---矩形為例

顏色說明

CAShapeLayer*layer = [CAShapeLayerlayer];layer.frame =CGRectMake(375/2-50,667/2-50,100,100);//設置背景色layer.backgroundColor = [UIColorcyanColor].CGColor;//設置描邊色layer.strokeColor = [UIColorblackColor].CGColor;//設置填充色layer.fillColor = [UIColorredColor].CGColor;[self.view.layer addSublayer:layer];

效果如圖顯示一個青色的矩形圖:

繪圖1

讀者估計會納悶,為啥設置的描邊色與填充色沒有作用,這是因為這兩種顏色需要UIBezierPath來繪制路徑,然后使用CAShapeLayer進行渲染,所以接下來就就在上面的那段代碼下簡單的添加一個UIBezierPath類路徑(溫馨提示,layer的背景與這兩種顏色最好不要共用)。

UIBezierPath*path = [UIBezierPathbezierPathWithRect:CGRectMake(0,0,100,100)];layer.path = path.CGPath;

繪圖2

可以發現填充色與描邊色有效果了。

2、繪制shape

//繪制矩形UIBezierPath*path = [UIBezierPathbezierPathWithRect:CGRectMake(0,0,100,100)];//繪制圓形路徑UIBezierPath*path = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,100,100)];//繪制自帶圓角的路徑UIBezierPath*path = [UIBezierPathbezierPathWithRoundedRect:CGRectMake(0,0,100,100) cornerRadius:30];//指定矩形某一個角加圓角(代碼示例為左上角)UIBezierPath*path = [UIBezierPathbezierPathWithRoundedRect:CGRectMake(0,0,100,100) byRoundingCorners:UIRectCornerTopLeftcornerRadii:CGSizeMake(50,50)];

繪圖3

3、繪制曲線(正弦曲線為例)

先來兩張效果圖:

繪圖4

繪圖5

說明:圖4只是比圖5多了填充色而已。

- (void)viewDidLoad {? ? [superviewDidLoad];// Do any additional setup after loading the view, typically from a nib.UIBezierPath*path = [selfstartPoint:CGPointMake(50,300) endPoint:CGPointMake(200,300) controlPoint:CGPointMake(125,200)];UIBezierPath*path1 = [selfstartPoint:CGPointMake(200,300) endPoint:CGPointMake(350,300) controlPoint:CGPointMake(275,400)];CAShapeLayer*layer = [selfcreateShapeLayer:[UIColororangeColor]];? ? layer.path = path.CGPath;CAShapeLayer*layer1 = [selfcreateShapeLayer:[UIColorgreenColor]];? ? layer1.path = path1.CGPath;}/**

配置貝塞爾曲線

@param startPoint 起始點

@param endPoint 結束點

@param controlPoint 控制點

@return UIBezierPath對象

*/- (UIBezierPath*)startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint{UIBezierPath*path = [UIBezierPathbezierPath];? ? [path moveToPoint:startPoint];? ? [path addQuadCurveToPoint:endPoint controlPoint:controlPoint];returnpath;}- (CAShapeLayer*)createShapeLayer:(UIColor*)color{CAShapeLayer*layer = [CAShapeLayerlayer];//? ? layer.frame = CGRectMake(0, 0, 50, 50);//設置背景色//? ? layer.backgroundColor = [UIColor cyanColor].CGColor;//設置描邊色layer.strokeColor = [UIColorblackColor].CGColor;//設置填充色layer.fillColor = color.CGColor;? ? [self.view.layer addSublayer:layer];returnlayer;}

4、曲線動畫

1)、直線

直線動畫

UIBezierPath*path = [UIBezierPathbezierPath];[path moveToPoint:CGPointMake(50,667/2)];[path addLineToPoint:CGPointMake(375/2,667/2)];[path addLineToPoint:CGPointMake(300,667/2)];CABasicAnimation*animation = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];//每次動畫的持續時間animation.duration =5;//動畫起始位置animation.fromValue = @(0);//動畫結束位置animation.toValue = @(1);//動畫重復次數animation.repeatCount =100;CAShapeLayer*layer = [selfcreateShapeLayerNoFrame:[UIColororangeColor]];layer.path = path.CGPath;layer.lineWidth =2.0;//設置圖形的弧度//? ? layer.strokeStart = 0;//? ? layer.strokeEnd = 0;[layer addAnimation:animation forKey:@"strokeEndAnimation"];//注:由于UIBezierPath已經設置路徑,所以動畫的路徑就不需要再次設置,只需要設置起始0與結束1就行,有需要可以設置動畫結束后是否需要返回原位置。

2)、曲線

曲線動畫.gif

UIBezierPath*path = [UIBezierPathbezierPath];//起始點[path moveToPoint:CGPointMake(50,667/2)];//結束點、兩個控制點[path addCurveToPoint:CGPointMake(330,667/2) controlPoint1:CGPointMake(125,200) controlPoint2:CGPointMake(185,450)];CABasicAnimation*animation = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];animation.duration =5;animation.fromValue = @(0);animation.toValue = @(1);animation.repeatCount =100;CAShapeLayer*layer = [selfcreateShapeLayerNoFrame:[UIColorclearColor]];layer.path = path.CGPath;layer.lineWidth =2.0;[layer addAnimation:animation forKey:@"strokeEndAnimation"];

3)、圓形

筆者目前的一個項目中就用到了這個功能。直接貼一張效果圖:

圓形動畫.gif

其實實現效果很簡單,只是把邊線加粗了然后實現動畫就可以了,還有一種思路就是畫兩個圓,截取中間的環,對大圓進行顏色漸變填充,小圓clear所有顏色再去實現動畫也能達到這樣的效果。

UIBezierPath*path = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(375/2-100,667/2-100,200,200)];CABasicAnimation*animation = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];animation.duration =3.0;animation.fromValue = @(0);animation.toValue = @(1);animation.repeatCount =100;CAShapeLayer*layer = [selfcreateShapeLayerNoFrame:[UIColorclearColor]];layer.path = path.CGPath;layer.lineWidth =25.0;//圓的起始位置,默認為0layer.strokeStart =0;//圓的結束位置,默認為1,如果值為0.75,則顯示3/4的圓layer.strokeEnd =1;[layer addAnimation:animation forKey:@"strokeEndAnimation"];

四、小結

iOS中畫圖類還有CoreGraphics,但筆者比較喜歡使用CAShapeLayer,且CAShapeLayer一般是與UIBezierPath連用的,如果有動畫功能的話,還可以加上CABasicAnimation。這篇文章只是對CAShapeLayer和UIBezierPath類如何使用和主要功能實現做了簡要的說明,還有一些項目中可能經常用到的圓形進度圈、下載圈,或者某些特效的實現,筆者可能在下一篇文章中簡析封裝步驟與代碼實現,有需要的讀者多多關注。

轉載自? http://www.lxweimin.com/p/139f4fbe7b6b

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容