日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CAShapeLayer和UIBezierPath

發(fā)布時(shí)間:2023/12/20 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CAShapeLayer和UIBezierPath 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一:貝塞爾曲線 UIBezierPath

使用UIBezierPath類可以創(chuàng)建基于矢量的路徑,這個(gè)類再UIKit中。此類是Core Graphics框架關(guān)于path的一個(gè)封裝。使用此類可以定義簡(jiǎn)單的形狀,如橢圓或者矩形,或者有多個(gè)直線和曲線段組成的形狀。

1、UIBezierPath基礎(chǔ)

UIBezierPath對(duì)象是CGPathRef數(shù)據(jù)類型的封裝。path如果是基于矢量形狀的,都是直線和曲線段去創(chuàng)建。我們使用只線段去創(chuàng)建矩形和多邊形,使用曲線段去創(chuàng)建弧(arc),圓或者其他復(fù)雜的曲線形狀。每一段都包括一個(gè)或者多個(gè)點(diǎn),繪圖命令定義如何詮釋這些點(diǎn)。每一個(gè)直線段或者曲線段的結(jié)束的地方是下一個(gè)的開始的地方。每一個(gè)連接的直線或者曲線段的集合成為subPath。一個(gè)UIBezierPath對(duì)象定義一個(gè)完整的路徑包括一個(gè)或者多個(gè)subpaths。

創(chuàng)建和使用一個(gè)path對(duì)象的過程是分開的。創(chuàng)建path是第一步,包含以下步驟:

  • (1)、創(chuàng)建一個(gè)UIBezierPath對(duì)象;
  • (2)、使用方法moveToPoint:去設(shè)置初始線段的起點(diǎn);
  • (3)、添加line或者curve去定義一個(gè)或者多個(gè)subpaths;
  • (4)、改變UIBezierPath對(duì)象跟繪圖相關(guān)的屬性。

例如:我們呢可以設(shè)置strokedPath的屬性lineWidth和lineJoinStyle。也可以設(shè)置filledPath的屬性u(píng)sersEvenOddFullRule。
當(dāng)創(chuàng)建path,我們應(yīng)該管理path上面的點(diǎn)相對(duì)于原點(diǎn)(0,0),這樣我們?cè)陔S后就可以很容易的移動(dòng)path了。為了繪制path對(duì)象,我們要用到stroke和fill方法。這些方法再current graphic context下渲染path的line和curve段。

2、使用UIBezierPath創(chuàng)建多邊形—在path下面添加直線條形成多邊形

多邊形是一些簡(jiǎn)單的形狀,這些形狀是由一些直線線條組成,我們可以用
(1)、 - (void)moveToPoint:(CGPoint)point;
(2)、 - (void)addLineToPoint:(CGPoint)point;
方法去構(gòu)建。

方法moveToPoint:設(shè)置我們想要?jiǎng)?chuàng)建形狀的起點(diǎn)。從這點(diǎn)開始,我們可以用方法addLineToPoint:去創(chuàng)建一個(gè)形狀的線段。
我們可以連續(xù)的創(chuàng)建line,每一個(gè)line的起點(diǎn)都是先前的終點(diǎn),終點(diǎn)就是指定的點(diǎn)。
下面的代碼描述了如何用線段去創(chuàng)建一個(gè)五邊形。第五條線通過調(diào)用 - (void)closePath;方法得到的,它連接了最后一個(gè)點(diǎn)(0,40)和第一個(gè)點(diǎn)(100,0)

說明:closePath方法不僅結(jié)束一個(gè)shape的subpath表述,它也在最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)之間畫一條線段,如果我們畫多邊形的話,這個(gè)一個(gè)便利的方法我們不需要去畫最后一條線。
例如:

- (void)drawRect:(CGRect)rect{[super drawRect:rect];UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIBezierPath* aPath = [UIBezierPath bezierPath];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理// Set the starting point of the shape.[aPath moveToPoint:CGPointMake(100.0, 0.0)];// Draw the lines[aPath addLineToPoint:CGPointMake(200.0, 40.0)];[aPath addLineToPoint:CGPointMake(160, 140)];[aPath addLineToPoint:CGPointMake(40.0, 140)];[aPath addLineToPoint:CGPointMake(0.0, 40.0)];[aPath closePath];//第五條線通過調(diào)用closePath方法得到的[aPath stroke];//Draws line 根據(jù)坐標(biāo)點(diǎn)連線// [aPath fill];//填充 }

3、使用UIBezierPath創(chuàng)建矩形

使用如下方法即可:

+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect;

例如:

- (void)drawRect:(CGRect)rect {[super drawRect:rect];UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIColor *fillColor = [UIColor yellowColor];[fillColor setFill];UIBezierPath* aPath = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 50)];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理[aPath stroke]; }

4、使用UIBezierPath創(chuàng)建圓形或者橢圓形

使用這個(gè)方法即可:

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect;理解:這個(gè)方法根據(jù)傳入的rect矩形參數(shù)繪制一個(gè)內(nèi)切曲線。當(dāng)傳入的rect是一個(gè)正方形時(shí),繪制的圖像是一個(gè)內(nèi)切圓;當(dāng)傳入的rect是一個(gè)長(zhǎng)方形時(shí),繪制的圖像是一個(gè)內(nèi)切橢圓。

例如:

- (void)drawRect:(CGRect)rect {[super drawRect:rect];UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIColor *fillColor = [UIColor yellowColor];[fillColor setFill];UIBezierPath* aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 100, 50)];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理[aPath stroke]; }

5、使用UIBezierPath創(chuàng)建一段弧線

使用這個(gè)方法:

+ (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;解釋:其中的參數(shù)分別指定:這段圓弧的中心,半徑,開始角度,結(jié)束角度,是否順時(shí)針方向。

例如:

#define pi 3.14159265359 #define DEGREES_TO_RADIANS(degrees) ((pi * degrees)/ 180) - (void)drawRect:(CGRect)rect {UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:75 startAngle:0 endAngle:DEGREES_TO_RADIANS(135) clockwise:YES];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理[aPath stroke]; }

6、UIBezierPath類提供了添加二次貝塞爾曲線和三次貝塞爾曲線的支持

曲線段在當(dāng)前點(diǎn)開始,在指定的點(diǎn)結(jié)束。曲線的形狀有開始點(diǎn),結(jié)束點(diǎn),一個(gè)或者多個(gè)控制點(diǎn)的切線定義。下圖顯示了兩種曲線類型的相似,以及控制點(diǎn)和curve形狀的關(guān)系。

(1)、繪制二次貝塞爾曲線

使用到這個(gè)方法:

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint; 解釋:其中的參數(shù)分別指定:結(jié)束點(diǎn),控制點(diǎn);


例如:

- (void)drawRect:(CGRect)rect {UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIBezierPath* aPath = [UIBezierPath bezierPath];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理[aPath moveToPoint:CGPointMake(20, 100)];[aPath addQuadCurveToPoint:CGPointMake(120, 100) controlPoint:CGPointMake(70, 0)];[aPath stroke]; }

(2)、繪制三次貝塞爾曲線

使用到這個(gè)方法:

- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;解釋:其中的參數(shù)分別指定:結(jié)束點(diǎn),第一個(gè)控制點(diǎn),第二個(gè)控制點(diǎn);


例如:

- (void)drawRect:(CGRect)rect {UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIBezierPath* aPath = [UIBezierPath bezierPath];aPath.lineWidth = 5.0;aPath.lineCapStyle = kCGLineCapRound; //線條拐角aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理[aPath moveToPoint:CGPointMake(20, 50)];[aPath addCurveToPoint:CGPointMake(220, 250) controlPoint1:CGPointMake(220, 50) controlPoint2:CGPointMake(20, 250)];[aPath stroke]; }

7、使用Core Graphics函數(shù)去修改path。

UIBezierPath類只是 CGPathRef數(shù)據(jù)類型和path繪圖屬性的一個(gè)封裝。雖然通常我們可以用UIBezierPath類的方法去添加直線段和曲線 段,UIBezierPath類還提供了一個(gè)屬性CGPath,我們可以用來直接修改底層的path data type。如果我們希望用Core Graphics 框架函數(shù)去創(chuàng)建path,則我們要用到此屬性。
有兩種方法可以用來修改和 UIBezierPath對(duì)象相關(guān)的path。可以完全的使用Core Graphics函數(shù)去修改path,也可以使用Core Graphics函數(shù)和UIBezierPath函數(shù)混合去修改。第一種方法在某些方面相對(duì)來說比較容易。我們可以創(chuàng)建一個(gè)CGPathRef數(shù)據(jù)類型, 并調(diào)用我們需要修改path信息的函數(shù)。
下面的代碼就是賦值一個(gè)新的CGPathRef給UIBezierPath對(duì)象。
例如:

- (void)drawRect:(CGRect)rect {UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色// Create the path dataCGMutablePathRef cgPath = CGPathCreateMutable();CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 20, 300, 300));CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 70, 200, 200));// Now create the UIBezierPath objectUIBezierPath* aPath = [UIBezierPath bezierPath];aPath.CGPath = cgPath;aPath.usesEvenOddFillRule = YES;[aPath stroke];// After assigning it to the UIBezierPath object, you can release// your CGPathRef data type safely.CGPathRelease(cgPath); }

如果我們使用Core Graphics函數(shù)和UIBezierPath函數(shù)混合方法,我們必須小心的移動(dòng)path 信息在兩者之間。因?yàn)閁IBezierPath類擁有自己底層的CGPathRef data type,我們不能簡(jiǎn)單的檢索該類型并直接的修改它。相反,我們應(yīng)該生成一個(gè)副本,然后修改此副本,然后賦值此副本給CGPath屬性,如下代碼:
例如:

- (void)drawRect:(CGRect)rect {UIColor *color = [UIColor redColor];[color set]; //設(shè)置線條顏色UIBezierPath* aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];// Get the CGPathRef and create a mutable version.CGPathRef cgPath = aPath.CGPath;CGMutablePathRef mutablePath = CGPathCreateMutableCopy(cgPath);// Modify the path and assign it back to the UIBezierPath objectCGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));aPath.CGPath = mutablePath;// Release both the mutable copy of the path.CGPathRelease(mutablePath);[aPath stroke]; }

8、rendering(渲染)Bezier Path對(duì)象的內(nèi)容。

當(dāng)創(chuàng)建一個(gè)UIBezierPath對(duì)象之后,我們可以使用它的stroke和fill方法在current graphics context中去渲染它。在調(diào)用這些方法之前,我們要進(jìn)行一些其他的任務(wù)去確保正確的繪制path。
使用UIColor類的方法去stroke和fill想要的顏色。
設(shè)置形狀在目標(biāo)視圖中的位置。如果我們 創(chuàng)建的path相對(duì)于原點(diǎn)(0,0),則我們可以給current drawing context應(yīng)用一個(gè)適當(dāng)?shù)腶ffie transform。例如,我想drawing一個(gè)形狀起始點(diǎn)在(0,0),我可以調(diào)用函數(shù)CGContextTranslateCTM,并指定水平和垂 直方向的translation值為10。調(diào)整graphic context相對(duì)于調(diào)整path對(duì)象的points是首選的方法,因?yàn)槲覀兛梢院苋菀椎谋4婧统蜂N先前的graphics state。
更新path對(duì)象的drawing 屬性。當(dāng)渲染path時(shí),UIBezierPath實(shí)例的drawing屬性會(huì)覆蓋graphics context下的屬性值。
下面的代碼實(shí)現(xiàn)了在一個(gè)自定義view中實(shí)現(xiàn)drawRect:方法中去繪制一個(gè)橢圓。橢圓邊框矩形的左上角位于視圖坐標(biāo)系統(tǒng)的點(diǎn)(50,50)處。
Drawing a path in a view
例如:

- (void)drawRect:(CGRect)rect {// Create an oval shape to draw.UIBezierPath* aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)];// Set the render colors[[UIColor blackColor] setStroke];[[UIColor redColor] setFill];CGContextRef aRef = UIGraphicsGetCurrentContext();// If you have content to draw after the shape,// save the current state before changing the transform//CGContextSaveGState(aRef);// Adjust the view's origin temporarily. The oval is// now drawn relative to the new origin point.CGContextTranslateCTM(aRef, 50, 50);// Adjust the drawing options as needed.aPath.lineWidth = 5;// Fill the path before stroking it so that the fill// color does not obscure the stroked line.[aPath fill];[aPath stroke];// Restore the graphics state before drawing any other content.//CGContextRestoreGState(aRef); }

二:CAShapeLayer

1、屬性

(1)、 @property CGPathRef path; 理解:從貝塞爾曲線獲取的形狀; (2)、 @property CGColorRef fillColor; 理解:閉環(huán)填充顏色; (3)、 @property(copy) NSString *fillRule; /* fillRule values. */ CA_EXTERN NSString *const kCAFillRuleNonZero __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); CA_EXTERN NSString *const kCAFillRuleEvenOdd __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); (4)、 @property CGColorRef strokeColor; 理解:邊緣線的顏色; (5)、 @property CGFloat strokeStart; 理解:控制開始的外觀; (6)、 @property CGFloat strokeEnd; 理解:控制結(jié)束的外觀; (7)、 @property CGFloat lineWidth; 理解:設(shè)置路徑的寬度,默認(rèn)為1; (8)、 @property(copy) NSString *lineCap; 理解:邊緣線的類型; /* lineCap values. */ CA_EXTERN NSString *const kCALineCapButt __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); CA_EXTERN NSString *const kCALineCapRound __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); CA_EXTERN NSString *const kCALineCapSquare __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); (9)、 @property(copy) NSString *lineJoin; 理解:連接方式類型 /* lineJoin values. */ CA_EXTERN NSString *const kCALineJoinMiter __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); CA_EXTERN NSString *const kCALineJoinRound __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0); CA_EXTERN NSString *const kCALineJoinBevel __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0);

2、步驟:

使用CAShapeLayer與UIBezierPath可以實(shí)現(xiàn)不在view的drawRect方法中就畫出一些想要的圖形

  • (1)、新建UIBezierPath對(duì)象bezierPath
  • (2)、新建CAShapeLayer對(duì)象caShapeLayer
  • (3)、將bezierPath的CGPath賦值給caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
  • (4)、把caShapeLayer添加到某個(gè)顯示該圖形的layer中

三、CAShapeLayer+ CAGradientLayer自定義路徑

使用: @property(strong) CALayer *mask;

例如:

#define degreesToRadians(x) (M_PI*(x)/180.0) - (void)viewDidLoad {[super viewDidLoad];UIView* bgView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];bgView.backgroundColor = [UIColor redColor];[self.view addSubview:bgView];//畫出一個(gè)完成的進(jìn)度的背景軌道//創(chuàng)建一個(gè)路徑圖層CAShapeLayer* trackLayer = [CAShapeLayer layer];trackLayer.frame = bgView.bounds;[bgView.layer addSublayer:trackLayer];trackLayer.fillColor = [[UIColor clearColor] CGColor];//指定path的渲染顏色trackLayer.strokeColor = [[UIColor redColor] CGColor];//背景同學(xué)你就甘心做背景吧,不要太明顯了,透明度小一點(diǎn)trackLayer.opacity = 1;//指定線的邊緣是圓的trackLayer.lineCap = kCALineCapRound;//線的寬度trackLayer.lineWidth = 4;//上面說明過了用來構(gòu)建圓形UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:(200-4)/2 startAngle:degreesToRadians(-210) endAngle:degreesToRadians(30) clockwise:YES];//把path傳遞給layer,然后layer會(huì)處理相應(yīng)的渲染,整個(gè)邏輯和CoreGraph是一致的。trackLayer.path =[path CGPath];//動(dòng)畫CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];animation.duration = 1;animation.fromValue = @(0.0);animation.toValue = @(1.0);[trackLayer addAnimation:animation forKey:@"strokeEnd"];//創(chuàng)建背景圖層CAGradientLayer *gradientLayer = [CAGradientLayer layer];[gradientLayer setColors:[NSArray arrayWithObjects:(id)[[[UIColor blackColor] colorWithAlphaComponent:1] CGColor],(id)[[[UIColor yellowColor] colorWithAlphaComponent:1] CGColor],(id)[[[UIColor blueColor] colorWithAlphaComponent:1] CGColor],(id)[[UIColor clearColor] CGColor],nil]];gradientLayer.frame = bgView.bounds;[gradientLayer setLocations:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],[NSNumber numberWithFloat:0.3],[NSNumber numberWithFloat:0.8],[NSNumber numberWithFloat:1.0],nil]];[gradientLayer setStartPoint:CGPointMake(0, 0.5)];[gradientLayer setEndPoint:CGPointMake(1, 0.5)];[gradientLayer setMask:trackLayer]; //用progressLayer來截取漸變層[bgView.layer addSublayer:gradientLayer]; }

總結(jié)

以上是生活随笔為你收集整理的CAShapeLayer和UIBezierPath的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。