前言
UIBezierPath這個(gè)類在UIKit中, 是Core Graphics框架關(guān)于path的一個(gè)封裝,使用此類可以定義簡單的形狀,比如我們常用到,矩形,圓形,橢圓,弧,或者不規(guī)則的多邊形。
UIBezierPath 基本使用方法
UIBezierPath對(duì)象是CGPathRef數(shù)據(jù)類型的封裝。path如果是基于矢量形狀的,都用直線或曲線去創(chuàng)建。我們一般使用UIBezierPath都是在重寫view的drawRect方法這種情形。我們用直線去創(chuàng)建矩形或多邊形,使用曲線創(chuàng)建弧或者圓。創(chuàng)建和使用path對(duì)象步驟:
1、 重寫View的drawRect方法
2、 創(chuàng)建UIBezierPath的對(duì)象
3、 使用方法moveToPoint:設(shè)置初始點(diǎn)
4、 根據(jù)具體要求使用UIBezierPath類方法繪圖(比如要畫線、矩形、圓、?。康龋?br>
5、 設(shè)置UIBezierPath對(duì)象相關(guān)屬性 (比如lineWidth、lineJoinStyle、aPath.lineCapStyle、color)
6、 使用stroke或者fill方法結(jié)束繪圖
比如我們想要畫一條線demo:
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set]; //設(shè)置線條顏色
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 10)];
[path addLineToPoint:CGPointMake(200, 80)];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound; //終點(diǎn)處理
path.lineJoinStyle = kCGLineJoinRound; //線條拐角
[path stroke];
}
其他基本使用方法
在介紹其他使用方法之前,我們先來看一下 path的幾個(gè)屬性,以便下面我進(jìn)行設(shè)置。
1、[color set];設(shè)置線條顏色,也就是相當(dāng)于畫筆顏色
2、path.lineWidth = 5.0;這個(gè)很好理解了,就是劃線的寬度
3、path.lineCapStyle這個(gè)線段起點(diǎn)是終點(diǎn)的樣式,這個(gè)樣式有三種:
(
- 1、
kCGLineCapButt該屬性值指定不繪制端點(diǎn), 線條結(jié)尾處直接結(jié)束。這是默認(rèn)值。 - 2、`kCGLineCapRound 該屬性值指定繪制圓形端點(diǎn), 線條結(jié)尾處繪制一個(gè)直徑為線條寬度的半圓。
- 3、
kCGLineCapSquare該屬性值指定繪制方形端點(diǎn)。 線條結(jié)尾處繪制半個(gè)邊長為線條寬度的正方形。需要說明的是,這種形狀的端點(diǎn)與“butt”形狀的端點(diǎn)十分相似,只是采用這種形式的端點(diǎn)的線條略長一點(diǎn)而已
)
4、path.lineJoinStyle這個(gè)屬性是用來設(shè)置兩條線連結(jié)點(diǎn)的樣式,同樣它也有三種樣式供我們選擇
( - 1、
kCGLineJoinMiter斜接 - 2、
kCGLineJoinRound圓滑銜接 - 3、
kCGLineJoinBevel斜角連接
)
5、[path stroke];用stroke得到的是不被填充的 view ,[path fill]; 用 fill 得到的內(nèi)部被填充的view,這點(diǎn)在下面的代碼還有繪制得到的圖片中有,可以體會(huì)一下這兩者的不同。
繪制多邊形
繪制多邊形,實(shí)際上就是又一些直線條連成,主要使用
moveToPoint:和addLineToPoint:方法去創(chuàng)建,moveToPoint:這個(gè)方法是設(shè)置起始點(diǎn),意味著從這個(gè)點(diǎn)開始,我們就可以使用addLineToPoint:去設(shè)置我們想要?jiǎng)?chuàng)建的多邊形經(jīng)過的點(diǎn),也就是兩線相交的那個(gè)點(diǎn),用addLineToPoint:去創(chuàng)建一個(gè)形狀的線段,我們可以連續(xù)創(chuàng)建line,每一個(gè)line的起點(diǎn)都是先前的終點(diǎn),終點(diǎn)就是指定的點(diǎn),將線段連接起來就是我們想要?jiǎng)?chuàng)建的多邊形了。
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set]; //設(shè)置線條顏色
UIBezierPath* path = [UIBezierPath bezierPath];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound; //線條拐角
path.lineJoinStyle = kCGLineJoinRound; //終點(diǎn)處理
[path moveToPoint:CGPointMake(200.0, 50.0)];//起點(diǎn)
// Draw the lines
[path addLineToPoint:CGPointMake(300.0, 100.0)];
[path addLineToPoint:CGPointMake(260, 200)];
[path addLineToPoint:CGPointMake(100.0, 200)];
[path addLineToPoint:CGPointMake(100, 70.0)];
[path closePath];//第五條線通過調(diào)用closePath方法得到的
// [path stroke];//Draws line 根據(jù)坐標(biāo)點(diǎn)連線
[path fill];//顏色填充
}
在這里我們可以看到最后第五條線是用
[path closePath];得到的,closePath方法不僅結(jié)束一個(gè)shape的subpath表述,它也在最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)之間畫一條線段,這個(gè)一個(gè)便利的方法我們不需要去畫最后一條線了, 哈哈哈哈。這里我們用到的是[path fill];//顏色填充進(jìn)行坐標(biāo)連點(diǎn),但是我們看見的是五邊形內(nèi)部被顏色填充了, 如果我們使用[path stroke];那我們得到的就是一個(gè)用線畫的五邊形。
畫矩形或者正方形
使用+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect這個(gè)方法,設(shè)置好坐標(biāo) frame 就好了,就像我們創(chuàng)建 view 一樣,好理解。
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set]; //設(shè)置線條顏色
UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 80)];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound; //線條拐角
path.lineJoinStyle = kCGLineJoinRound; //終點(diǎn)處理
[path stroke];
}
創(chuàng)建圓形或者橢圓形
使用+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect這個(gè)方法創(chuàng)建圓形或者橢圓形。
傳入的rect矩形參數(shù)繪制一個(gè)內(nèi)切曲線,如果我們傳入的rect是矩形就得到矩形的內(nèi)切橢圓,如果傳入的是 正方形得到的就是正方形的內(nèi)切圓。
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:90 startAngle:0 endAngle:TO_RADIAUS(120) clockwise:YES];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[path stroke];
}
創(chuàng)建一段弧線
使用+ (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwis這個(gè)方法創(chuàng)建一段弧線,介紹一下這個(gè)方法中的參數(shù):
/*
ArcCenter: 原點(diǎn)
radius: 半徑
startAngle: 開始角度
endAngle: 結(jié)束角度
clockwise: 是否順時(shí)針方向
*/

繪制二次貝塞爾曲線
使用- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint這個(gè)方法繪制二次貝塞爾曲線。曲線段在當(dāng)前點(diǎn)開始,在指定的點(diǎn)結(jié)束,
一個(gè)控制點(diǎn)的切線定義。下圖顯示了兩種曲線類型的相似,以及控制點(diǎn)和curve形狀的關(guān)系:

- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
/*
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
Parameters
endPoint
The end point of the curve.
controlPoint
The control point of the curve.
*/
[path moveToPoint:CGPointMake(40, 150)];
[path addQuadCurveToPoint:CGPointMake(140, 200) controlPoint:CGPointMake(20, 40)];
[path stroke];
}
繪制三次貝塞爾曲線
使用這個(gè)方法繪制三次貝塞爾曲線
- (void)addCurveToPoint:(CGPoint)endPoint
controlPoint1:(CGPoint)controlPoint1
controlPoint2:(CGPoint)controlPoint2
這個(gè)方法繪制三次貝塞爾曲線。曲線段在當(dāng)前點(diǎn)開始,在指定的點(diǎn)結(jié)束,兩個(gè)控制點(diǎn)的切線定義。下圖顯示了兩種曲線類型的相似,以及控制點(diǎn)和curve形狀的關(guān)系:
圖片.png
- (void)drawRect:(CGRect)rect {
/*
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
Parameters
endPoint
The end point of the curve.
controlPoint1
The first control point to use when computing the curve.
controlPoint2
The second control point to use when computing the curve.
*/
UIColor *color = [UIColor redColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[path moveToPoint:CGPointMake(20, 200)];
[path addCurveToPoint:CGPointMake(260, 200) controlPoint1:CGPointMake(140, 0) controlPoint2:CGPointMake(140, 400)];
[path stroke];
}
畫帶圓角的矩形

使用
+ (instancetype)bezierPathWithRect:(CGRect)rect;這個(gè)方法繪制,這個(gè)方法和bezierPathWithRect:類似,繪制一個(gè)帶內(nèi)切圓的矩形。
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set]; //設(shè)置線條顏色
UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 80)];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound; //線條拐角
path.lineJoinStyle = kCGLineJoinRound; //終點(diǎn)處理
[path stroke];
}
指定矩形的某個(gè)角為圓角

使用
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;這個(gè)方法繪制。參數(shù)的意思:rect 繪制矩形的 frame,corners指定使哪個(gè)角為圓角,圓角類型為:
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
UIRectCornerTopLeft = 1 << 0,
UIRectCornerTopRight = 1 << 1,
UIRectCornerBottomLeft = 1 << 2,
UIRectCornerBottomRight = 1 << 3,
UIRectCornerAllCorners = ~0UL
};
用來指定需要設(shè)置的角。cornerRadii 圓角的半徑
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor redColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) byRoundingCorners:UIRectCornerTopRight cornerRadii:CGSizeMake(20, 20)];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
path.lineWidth = 5.0;
[path stroke];
}
CAShapeLayer
CAShapeLayer是在其坐標(biāo)系統(tǒng)內(nèi)繪制貝塞爾曲線(UIBezierPath)的。因此,使用CAShapeLayer需要與UIBezierPath一起使用。
它有一個(gè)path屬性,而UIBezierPath就是對(duì)CGPathRef類型的封裝,因此這兩者配合起來使用才可以的哦!
CAShapeLayer與UIBezierPath的關(guān)系:
-
CAShapeLayer中shape代表形狀的意思,所以需要形狀才能生效
貝塞爾曲線可以創(chuàng)建基于矢量的路徑,而UIBezierPath類是對(duì)CGPathRef的封裝
貝塞爾曲線給CAShapeLayer提供路徑,CAShapeLayer在提供的路徑中進(jìn)行渲染。路徑會(huì)閉環(huán),所以繪制出了Shape
用于CAShapeLayer的貝塞爾曲線作為path,其path是一個(gè)首尾相接的閉環(huán)的曲線,即使該貝塞爾曲線不是一個(gè)閉環(huán)的曲線
CAShapeLayer與UIBezierPath畫圓
- (CAShapeLayer *)drawCircle {
CAShapeLayer *circleLayer = [CAShapeLayer layer];
// 指定frame,只是為了設(shè)置寬度和高度
circleLayer.frame = CGRectMake(0, 0, 200, 200);
// 設(shè)置居中顯示
circleLayer.position = self.view.center;
// 設(shè)置填充顏色
circleLayer.fillColor = [UIColor clearColor].CGColor;
// 設(shè)置線寬
circleLayer.lineWidth = 2.0;
// 設(shè)置線的顏色
circleLayer.strokeColor = [UIColor redColor].CGColor;
// 使用UIBezierPath創(chuàng)建路徑
CGRect frame = CGRectMake(0, 0, 200, 200);
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame];
// 設(shè)置CAShapeLayer與UIBezierPath關(guān)聯(lián)
circleLayer.path = circlePath.CGPath;
// 將CAShaperLayer放到某個(gè)層上顯示
[self.view.layer addSublayer:circleLayer]; return circleLayer;}
UIBezierPath CAShapeLayer結(jié)合畫虛線
登錄例子下載地址:
demo下載地址
UIColor *color = [UIColor redColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[path moveToPoint:CGPointMake(40, 150)];
[path addQuadCurveToPoint:CGPointMake(140, 200) controlPoint:CGPointMake(180, 40)];
[path stroke];
CAShapeLayer *_shapeLine = [CAShapeLayer layer];
_shapeLine.frame = self.bounds;
_shapeLine.lineJoin = kCALineCapButt;
_shapeLine.lineDashPattern = @[@(20),@(5)];
_shapeLine.fillColor = [UIColor clearColor].CGColor;
_shapeLine.strokeColor = [UIColor greenColor].CGColor;
_shapeLine.path = path.CGPath;
[self.layer addSublayer:_shapeLine];
UIBezierPath CAShapeLayer結(jié)合畫虛線 加入動(dòng)畫
self.backgroundColor = [UIColor whiteColor];
UIColor *color = [UIColor greenColor];
[color set];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = 5.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[path moveToPoint:CGPointMake(40, 150)];
[path addQuadCurveToPoint:CGPointMake(140, 200) controlPoint:CGPointMake(180, 40)];
[path stroke];
CAShapeLayer *_shapeLine = [CAShapeLayer layer];
_shapeLine.frame = self.bounds;
_shapeLine.lineJoin = kCALineCapButt;
_shapeLine.lineDashPattern = @[@(20),@(5)];
_shapeLine.fillColor = [UIColor clearColor].CGColor;
_shapeLine.strokeColor = [UIColor greenColor].CGColor;
_shapeLine.path = path.CGPath;
[self.layer addSublayer:_shapeLine];
CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.fromValue = [NSValue valueWithCGPoint:_shapeLine.position];
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320 - 80, _shapeLine.position.y)];
moveAnimation.autoreverses = YES;
moveAnimation.repeatCount = MAXFLOAT;
moveAnimation.duration = 2;
[_shapeLine addAnimation:moveAnimation forKey:@"sf"];
參考資料:
iOS 動(dòng)畫效果:Core Animation & Facebook
拍電影與CABasicAnimation
標(biāo)哥的技術(shù)博客
CABasicAnimation使用總結(jié)
蘋果文檔
放肆的使用UIBezierPath和CAShapeLaye
