UIKit中的UIBezierPath是Core Graphics框架關(guān)于path的一個(gè)封裝??梢詣?chuàng)建基于矢量的路徑,例如橢圓或者矩形,或者有多個(gè)直線和曲線段組成的形狀.
屬性:
-
lineWidth:線寬屬性定義了UIBezierPath對(duì)象中繪制的曲線規(guī)格. 默認(rèn)為: 1.0 -
lineCapStyle:應(yīng)用于曲線的終點(diǎn)和起點(diǎn). 該屬性在一個(gè)閉合子路經(jīng)中是無(wú)效果的. 默認(rèn)為: kCGLineCapButt
枚舉值:
typedef CF_ENUM(int32_t, CGLineCap) {
kCGLineCapButt,
kCGLineCapRound,
kCGLineCapSquare
};
對(duì)應(yīng)樣式:

-
lineJoinStyle:曲線連接點(diǎn)的樣式.
枚舉值:
typedef CF_ENUM(int32_t, CGLineJoin) {
kCGLineJoinMiter,
kCGLineJoinRound,
kCGLineJoinBevel
};
對(duì)應(yīng)樣式:

-
miterLimit:兩條線交匯處內(nèi)角和外角之間的最大距離, 僅當(dāng)連接點(diǎn)樣式為 kCGLineJoinMiter時(shí)生效.
圖解:

-
flatness:渲染精度(表示真實(shí)曲線的點(diǎn)和渲染曲線的點(diǎn)的最大允許距離)。值越小,精度越高。default:0.6。 -
usesEvenOddFillRule:是否使用基偶填充規(guī)則。兩種規(guī)則的詳細(xì)介紹
設(shè)置為 YES, 則路徑將會(huì)使用 基偶規(guī)則 (even-odd) 進(jìn)行填充.
設(shè)置為 NO, 則路徑將會(huì)使用 非零規(guī)則 (non-zero) 規(guī)則進(jìn)行填充.
-
CGPath:一個(gè)不可變的 CGPathRef 對(duì)象
他可以傳入 CoreGraphics 提供的函數(shù)中你可以是用 CoreGraphics 框架提供的方法創(chuàng)建一個(gè)路徑, 并給這個(gè)屬性賦值, 當(dāng)時(shí)設(shè)置了一個(gè)新的路徑后, 這個(gè)將會(huì)對(duì)你給出的路徑對(duì)象進(jìn)行 Copy 操作
-
currentPoint:下一條繪制的直線或曲線的起始點(diǎn)。如果當(dāng)前路徑為空, 那么該屬性的值將會(huì)是 CGPointZero -
bounds:路徑覆蓋的矩形區(qū)域。該屬性描述的是一個(gè)能夠完全包含路徑中所有點(diǎn)的一個(gè)最小的矩形區(qū)域. 該區(qū)域包含二次貝塞爾曲線和三次貝塞爾曲線的控制點(diǎn). -
empty:路徑是否為空。 <注>: 就算你僅僅調(diào)用了 moveToPoint 方法那么當(dāng)前路徑也被看做不為空.
創(chuàng)建實(shí)例對(duì)象:
- ? 創(chuàng)建
+ (instancetype) bezierPath;
- by 矩形
/**
* 該方法將會(huì)創(chuàng)建一個(gè)閉合路徑, 起始點(diǎn)是 rect 參數(shù)的的 origin, 并且按照順時(shí)針?lè)较蛱砑又本€, 最終形成矩形
* @param rect: 矩形路徑的 Frame
*/
+ (instancetype)bezierPathWithRect:(CGRect)rect;
- by 橢圓
/**
* 該方法將會(huì)創(chuàng)建一個(gè)閉合路徑, 該方法會(huì)通過(guò)順時(shí)針的繪制貝塞爾曲線, 繪制出一個(gè)近似橢圓的形狀. 如果 rect 參數(shù)指定了一個(gè)矩形, 那么該 UIBezierPath 對(duì)象將會(huì)描述一個(gè)圓形.
* @param rect: 矩形路徑的 Frame
*/
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
- by 圓角矩形:
/**
* 該方法將會(huì)創(chuàng)建一個(gè)閉合路徑, 該方法會(huì)順時(shí)針?lè)较蜻B續(xù)繪制直線和曲線. 當(dāng) rect 為正方形時(shí)且 cornerRadius 等于邊長(zhǎng)一半時(shí), 則該方法會(huì)描述一個(gè)圓形路徑.
* @param rect: 矩形路徑的 Frame
* @param cornerRadius: 矩形的圓角半徑
*/
+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect
cornerRadius:(CGFloat)cornerRadius;
可以指定矩形的哪個(gè)角為圓角:
/**
* 該方法將會(huì)創(chuàng)建一個(gè)閉合路徑, 該方法會(huì)順時(shí)針?lè)较蜻B續(xù)繪制直線和曲線.
* @param rect: 矩形路徑的 Frame
* @param corners: UIRectCorner 枚舉類(lèi)型, 指定矩形的哪個(gè)角變?yōu)閳A角
* @param cornerRadii: 矩形的圓角半徑
*/
+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect
byRoundingCorners:(UIRectCorner)corners
cornerRadii:(CGSize)cornerRadii;
- by 圓弧
/**
* 該方法會(huì)創(chuàng)建出一個(gè)開(kāi)放路徑, 創(chuàng)建出來(lái)的圓弧是圓的一部分. 在默認(rèn)的坐標(biāo)系統(tǒng)中, 開(kāi)始角度 和 結(jié)束角度 都是基于單位圓的(看下面這張圖). 調(diào)用這個(gè)方法之后, currentPoint 將會(huì)設(shè)置為圓弧的結(jié)束點(diǎn).
* 舉例來(lái)說(shuō): 指定其實(shí)角度為0, 指定結(jié)束角度為π, 設(shè)置 clockwise 屬性為 YES, 將會(huì)繪制出圓的下半部分.
* 然而當(dāng)我們不修改起始角度 和 結(jié)束角度, 我們僅僅將 clockwise 角度設(shè)置為 NO, 則會(huì)繪制出來(lái)一個(gè)圓的上半部分.
* @param center: 圓心
* @param radius: 半徑
* @param startAngle: 起始角度
* @param endAngle: 結(jié)束角度
* @param clockwise: 是否順時(shí)針繪制
*/
+ (instancetype) bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise;

)
- by CGPath
+ (instancetype) bezierPathWithCGPath:(CGPathRef)CGPath;
- by 反方向Path(這里的方向是指繪制方向)。
/**
* @return: 返回一個(gè)新的 UIBezierPath 對(duì)象, 形狀和原來(lái)路徑的形狀一樣,
* 但是繪制的方向相反.
*/
- (UIBezierPath *) bezierPathByReversingPath;
構(gòu)造或添加路徑:
- 將對(duì)象的
currentPoint移到某個(gè)點(diǎn)。(對(duì)于大多數(shù)構(gòu)造路徑相關(guān)的方法而言, 在你繪制直線或曲線之前, 需要先調(diào)用這個(gè)方法.)
/**
* 如果當(dāng)前有正在繪制的子路徑, 該方法則會(huì)隱式的結(jié)束當(dāng)前路徑,
* 并將 currentPoint 設(shè)置為指定點(diǎn). 當(dāng)上一條子路徑被終止, 該方法
* 實(shí)際上并不會(huì)去閉合上一條子路徑. 所以上一條自路徑的起始點(diǎn) 和
* 結(jié)束點(diǎn)并沒(méi)有被鏈接.
* @param point: 當(dāng)前坐標(biāo)系統(tǒng)中的某一點(diǎn)
*/
- (void)moveToPoint:(CGPoint)point;
- 追加
一條直線
/**
* 該方法將會(huì)從 currentPoint 到 指定點(diǎn) 鏈接一條直線.
* Note: 在追加完這條直線后, 該方法將會(huì)更新 currentPoint 為 指定點(diǎn)
* 調(diào)用該方法之前, 你必須先設(shè)置 currentPoint. 如果當(dāng)前繪制路徑
* 為空, 并且未設(shè)置 currentPoint, 那么調(diào)用該方法將不會(huì)產(chǎn)生任何
* 效果.
* @param point: 繪制直線的終點(diǎn)坐標(biāo), 當(dāng)前坐標(biāo)系統(tǒng)中的某一點(diǎn)
*/
- (void)addLineToPoint:(CGPoint)point;
- 追加
一條圓弧
/**
* 該方法將會(huì)從 currentPoint 添加一條指定的圓弧.
* 該方法的介紹和構(gòu)造方法中的一樣. 請(qǐng)前往上文查看
* @param center: 圓心
* @param radius: 半徑
* @param startAngle: 起始角度
* @param endAngle: 結(jié)束角度
* @param clockwise: 是否順時(shí)針繪制
*/
- (void)addArcWithCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);
- 追加
一條三次貝塞爾曲線
/**
* 該方法將會(huì)從 currentPoint 到 指定的 endPoint 追加一條三次貝塞爾曲線.
* 三次貝塞爾曲線的彎曲由兩個(gè)控制點(diǎn)來(lái)控制. 如下圖所示
* Note: 調(diào)用該方法前, 你必須先設(shè)置 currentPoint, 如果路徑為空,
* 并且尚未設(shè)置 currentPoint, 調(diào)用該方法則不會(huì)產(chǎn)生任何效果.
* 當(dāng)添加完貝塞爾曲線后, 該方法將會(huì)自動(dòng)更新 currentPoint 為
* 指定的結(jié)束點(diǎn)
* @param endPoint: 終點(diǎn)
* @param controlPoint1: 控制點(diǎn)1
* @param controlPoint2: 控制點(diǎn)2
*/
- (void)addCurveToPoint:(CGPoint)endPoint
controlPoint1:(CGPoint)controlPoint1
controlPoint2:(CGPoint)controlPoint2;
圖解:

)
- 追加
一條二次貝塞爾曲線:
/**
* 該方法將會(huì)從 currentPoint 到 指定的 endPoint 追加一條二次貝塞爾曲線.
* currentPoint、endPoint、controlPoint 三者的關(guān)系最終定義了二次貝塞爾曲線的形狀.
* 二次貝塞爾曲線的彎曲由一個(gè)控制點(diǎn)來(lái)控制. 如下圖所示
* Note: 調(diào)用該方法前, 你必須先設(shè)置 currentPoint, 如果路徑為空,
* 并且尚未設(shè)置 currentPoint, 調(diào)用該方法則不會(huì)產(chǎn)生任何效果.
* 當(dāng)添加完貝塞爾曲線后, 該方法將會(huì)自動(dòng)更新 currentPoint 為
* 指定的結(jié)束點(diǎn)
* @param endPoint: 終點(diǎn)
* @param controlPoint: 控制點(diǎn)
*/
- (void)addQuadCurveToPoint:(CGPoint)endPoint
controlPoint:(CGPoint)controlPoint;
圖解:

- 追加 UIBezierPath 實(shí)例對(duì)象
/**
* 該方法將會(huì)在當(dāng)前 UIBezierPath 對(duì)象的路徑中追加
* 指定的 UIBezierPath 對(duì)象中的內(nèi)容.
*/
- (void)appendPath:(UIBezierPath *)bezierPath;
虛線路徑:
- 構(gòu)建一條虛線路徑:
/**
* @param pattern: 該屬性是一個(gè) C 語(yǔ)言的數(shù)組, 其中每一個(gè)元素都是 CGFloat
* 數(shù)組中的元素代表著線段每一部分的長(zhǎng)度, 第一個(gè)元素代表線段的第一條線,
* 第二個(gè)元素代表線段中的第一個(gè)間隙. 這個(gè)數(shù)組中的值是輪流的. 來(lái)解釋一下
* 什么叫輪流的.
* 舉個(gè)例子: 聲明一個(gè)數(shù)組 CGFloat dash[] = @{3.0, 1.0};
* 這意味著繪制的虛線的第一部分長(zhǎng)度為3.0, 第一個(gè)間隙長(zhǎng)度為1.0, 虛線的
* 第二部分長(zhǎng)度為3.0, 第二個(gè)間隙長(zhǎng)度為1.0. 以此類(lèi)推.
* @param count: 這個(gè)參數(shù)是 pattern 數(shù)組的個(gè)數(shù)
* @param phase: 這個(gè)參數(shù)代表著, 虛線從哪里開(kāi)始繪制.
* 舉個(gè)例子: 這是 phase 為 6. pattern[] = @{5, 2, 3, 2}; 那么虛線將會(huì)
* 第一個(gè)間隙的中間部分開(kāi)始繪制, 如果不是很明白就請(qǐng)繼續(xù)往下看,
* 下文實(shí)戰(zhàn)部分會(huì)對(duì)虛線進(jìn)行講解.
*/
- (void)setLineDash:(const CGFloat *)pattern
count:(NSInteger)count
phase:(CGFloat)phase;
- 獲取虛線的模式:
/**
* 該方法可以重新獲取之前設(shè)置過(guò)的虛線樣式.
* Note: pattern 這個(gè)參數(shù)的容量必須大于該方法返回?cái)?shù)組的容量.
* 如果無(wú)法確定數(shù)組的容量, 那么可以調(diào)用兩次該方法, 第一次
* 調(diào)用該方法的時(shí)候, 傳入 count 參數(shù), 然后在用 count 參數(shù)
* 來(lái)申請(qǐng) pattern 數(shù)組的內(nèi)存空間. 然后再第二次正常的調(diào)用該方法
*/
- (void)getLineDash:(CGFloat *)pattern
count:(NSInteger *)count
phase:(CGFloat *)phase;
Demo:
- (void) typeDashLine {
// 1. 先創(chuàng)建三條路徑, 有對(duì)比更有助于理解
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint: CGPointMake(80, 40)];
[path addLineToPoint: CGPointMake(self.frame.size.width - 40, 40)];
path.lineWidth = 2;
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint: CGPointMake(80, 80)];
[path1 addLineToPoint: CGPointMake(self.frame.size.width - 40, 80)];
path1.lineWidth = 2;
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint: CGPointMake(80, 120)];
[path2 addLineToPoint: CGPointMake(self.frame.size.width - 40, 120)];
path2.lineWidth = 2;
// 2. 這部分是配置三條路徑虛線的規(guī)格, 重點(diǎn)主要是這部分.
CGFloat dashLineConfig[] = {8.0, 4.0};
[path setLineDash: dashLineConfig
count: 2
phase: 0];
CGFloat dashLineConfig1[] = {8.0, 4.0, 16.0, 8.0};
[path1 setLineDash: dashLineConfig1
count: 4
phase: 0];
CGFloat dashLineConfig2[] = {8.0, 4.0, 16.0, 8.0};
[path2 setLineDash: dashLineConfig2
count: 4
phase: 12];
// 3. 繪制
[[UIColor orangeColor] set];
[path stroke];
[path1 stroke];
[path2 stroke];
}
顯示效果:

)
更改路徑:
- 關(guān)閉當(dāng)前子路徑:
/**
* 該方法將會(huì)從 currentPoint 到子路經(jīng)的起點(diǎn) 繪制一條直線,
* 以此來(lái)關(guān)閉當(dāng)前的自路徑. 緊接著該方法將會(huì)更新 currentPoint
* 為 剛添加的這條直線的終點(diǎn), 也就是當(dāng)前子路經(jīng)的起點(diǎn).
*/
- (void)closePath;
- 刪除
UIBezierPath對(duì)象中的所有點(diǎn), 效果也就等同于刪除了所有子路經(jīng):
- (void)removeAllPoints;
-
剪切路徑:
/**
* 該方法將會(huì)修改當(dāng)前繪圖上下文的可視區(qū)域.
* 當(dāng)調(diào)用這個(gè)方法之后, 會(huì)導(dǎo)致接下來(lái)所有的渲染
* 操作, 只會(huì)在剪切下來(lái)的區(qū)域內(nèi)進(jìn)行, 區(qū)域外的
* 內(nèi)容將不會(huì)被渲染.
* 如果你希望執(zhí)行接下來(lái)的繪圖時(shí), 刪除剪切區(qū)域,
* 那么你必須在調(diào)用該方法前, 先使用 CGContextSaveGState 方法
* 保存當(dāng)前的繪圖狀態(tài), 當(dāng)你不再需要這個(gè)剪切區(qū)域
* 的時(shí)候, 你只需要使用 CGContextRestoreGState 方法
* 來(lái)恢復(fù)之前保存的繪圖狀態(tài)就可以了.
* @param blendMode: 混合模式?jīng)Q定了如何和
* 已經(jīng)存在的被渲染過(guò)的內(nèi)容進(jìn)行合成
* @param alpha: 填充路徑時(shí)的透明度
*/
- (void)addClip;
- 放射變換操作:
/**
* 該方法將會(huì)直接對(duì)路徑中的所有點(diǎn)進(jìn)行指定的放射
* 變換操作.
*/
- (void)applyTransform:(CGAffineTransform)transform;
繪制相關(guān):
- 填充路徑:
/**
* 該方法當(dāng)前的填充顏色 和 繪圖屬性對(duì)路徑的封閉區(qū)域進(jìn)行填充.
* 如果當(dāng)前路徑是一條開(kāi)放路徑, 該方法將會(huì)隱式的將路徑進(jìn)行關(guān)閉后進(jìn)行填充
* 該方法在進(jìn)行填充操作之前, 會(huì)自動(dòng)保存當(dāng)前繪圖的狀態(tài), 所以我們不需要
* 自己手動(dòng)的去保存繪圖狀態(tài)了.
*/
- (void)fill;
- 使用混合模式填充路徑:
/**
* 該方法當(dāng)前的填充顏色 和 繪圖屬性 (外加指定的混合模式 和 透明度)
* 對(duì)路徑的封閉區(qū)域進(jìn)行填充. 如果當(dāng)前路徑是一條開(kāi)放路徑, 該方法將
* 會(huì)隱式的將路徑進(jìn)行關(guān)閉后進(jìn)行填充
* 該方法在進(jìn)行填充操作之前, 會(huì)自動(dòng)保存當(dāng)前繪圖的狀態(tài), 所以我們不需要
* 自己手動(dòng)的去保存繪圖狀態(tài)了.
*
* @param blendMode: 混合模式?jīng)Q定了如何和已經(jīng)存在的被渲染過(guò)的內(nèi)容進(jìn)行合成
* @param alpha: 填充路徑時(shí)的透明度
*/
- (void)fillWithBlendMode:(CGBlendMode)blendMode
alpha:(CGFloat)alpha;
- 繪制路徑:(一般用于將路徑相關(guān)設(shè)置完成后的最后一步操作).
- (void)stroke;
判斷方法:
- 是否包含某個(gè)點(diǎn):
/**
* 該方法返回一個(gè)布爾值, 當(dāng)曲線的覆蓋區(qū)域包含
* 指定的點(diǎn)(內(nèi)部點(diǎn)), 則返回 YES, 否則返回 NO.
* Note: 如果當(dāng)前的路徑是一個(gè)開(kāi)放的路徑, 那么
* 就算指定點(diǎn)在路徑覆蓋范圍內(nèi), 該方法仍然會(huì)
* 返回 NO, 所以如果你想判斷一個(gè)點(diǎn)是否在一個(gè)
* 開(kāi)放路徑的范圍內(nèi)時(shí), 你需要先Copy一份路徑,
* 并調(diào)用 -(void)closePath; 將路徑封閉, 然后
* 再調(diào)用此方法來(lái)判斷指定點(diǎn)是否是內(nèi)部點(diǎn).
* @param point: 指定點(diǎn).
*/
- (BOOL) containsPoint:(CGPoint)point;
Demo實(shí)例:
- 屬性方法簡(jiǎn)單應(yīng)用:
//========================================================
//>>>Part one : 創(chuàng)建UIBezierPath對(duì)象。
//========================================================
//1、通過(guò)矩形:
UIBezierPath * rectPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 30, 50)];
/**
判斷相關(guān):
*/
//ONE:是否包含。
BOOL isContain = [rectPath containsPoint:CGPointMake(25, 24)];
if (isContain) {
NSLog(@"contain");
}
//TWO:路徑是否為空。
BOOL isEmpty = [rectPath isEmpty];
if (!isEmpty) {
NSLog(@"not empty");
}
/**
相關(guān)屬性:
*/
rectPath.lineWidth = 3;
rectPath.lineCapStyle = kCGLineCapSquare; //曲線終點(diǎn)樣式,不適用于閉合路徑。
rectPath.lineJoinStyle = kCGLineJoinMiter; //曲線連接樣式。
rectPath.miterLimit = 2; //內(nèi)外角最大距離。
rectPath.flatness = 0.6; //默認(rèn)0.6,越低精度越高。
rectPath.usesEvenOddFillRule = YES; //是否適用奇偶填充規(guī)則。默認(rèn)非零規(guī)則填充。
NSLog(@"覆蓋的矩形區(qū)域:%@",[NSValue valueWithCGRect:rectPath.bounds]);//判斷覆蓋的矩形區(qū)域
[[UIColor orangeColor]set];
[rectPath stroke];
//2、通過(guò)橢圓(矩形的內(nèi)切橢圓)
UIBezierPath * ovalPath= [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 70, 30, 50)];
[[UIColor redColor]set];
[ovalPath stroke];
//3、通過(guò)圓角矩形:
UIBezierPath * cornerRectPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 130, 30, 50) cornerRadius:3];
[[UIColor blackColor] set];
[cornerRectPath stroke];
//4、通過(guò)圓弧:
UIBezierPath * arcPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(60, 200) radius:50 startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
[[UIColor brownColor] set];
arcPath.lineWidth = 4;
[arcPath stroke];
//5、通過(guò)path。
CGPathRef pathRef = CGPathCreateWithRect(CGRectMake(0, 280, 30, 50), nil);
UIBezierPath * pathPath = [UIBezierPath bezierPathWithCGPath:pathRef];
[[UIColor redColor]set];
[pathPath stroke];
//========================================================
//>>>Part two:構(gòu)造路徑:
//========================================================
UIBezierPath * allocPath = [UIBezierPath bezierPath];
allocPath.lineWidth= 4;
[allocPath moveToPoint:CGPointMake(50, 350)];
//追加一條直線路徑:
// [allocPath addLineToPoint:CGPointMake(50, 400)];
//追加一條圓?。?當(dāng)起始點(diǎn)到圓心的距離大于半徑的時(shí)候,起始點(diǎn)到距離圓心半徑的點(diǎn)上會(huì)作一條直線)
// [allocPath addArcWithCenter:CGPointMake(50, 400) radius:50 startAngle:M_PI_2+M_PI endAngle:M_PI_2 clockwise:NO];
//追加一條三次貝塞爾曲線:
// [allocPath addCurveToPoint:CGPointMake(50, 400) controlPoint1:CGPointMake(60, 370) controlPoint2:CGPointMake(30, 385)];
//追加一條二次貝塞爾曲線;
[allocPath addQuadCurveToPoint:CGPointMake(50, 400) controlPoint:CGPointMake(30, 385)];
//關(guān)閉路徑:
[allocPath closePath];
//刪除所有點(diǎn):
// [allocPath removeAllPoints];
//添加一個(gè)路徑到當(dāng)前路徑中來(lái)。
// [allocPath appendPath:pathPath];
//填充;
// [allocPath fill];
//選擇將以何種混合方式進(jìn)行填充。//?
// [allocPath fillWithBlendMode:kCGBlendModeLighten alpha:0.8];
[[UIColor orangeColor] set];
[allocPath stroke];
[[UIColor redColor]setFill];
UIRectFill(CGRectMake(100, 50, 100, 50));
CAShapeLayer
屬性:
大多屬性和UIBezierPath的屬性類(lèi)似。
path: CGPathRef 對(duì)象,圖形邊線路徑。fillColor:CGColorRef對(duì)象,圖形填充色,默認(rèn)為黑色。fillRule:填充規(guī)則。類(lèi)似于UIBezierPath的fillMode屬性。
kCAFillRuleNonZero : 非零環(huán)繞數(shù)規(guī)則。
這個(gè)規(guī)則通過(guò)從canvas上的某個(gè)點(diǎn)往任一方向繪制射線到無(wú)窮遠(yuǎn),然后檢查圖形的線段和射線相交的點(diǎn),來(lái)確定“內(nèi)部區(qū)域”。從0開(kāi)始計(jì)數(shù),每次路徑線段是從左到右穿過(guò)射線就加一,從右到左的就減一。通過(guò)計(jì)算交叉點(diǎn),如果結(jié)果是0,則這個(gè)點(diǎn)在路徑外邊,不然,就是在里邊。
[圖片上傳失敗...(image-4ee41e-1552033143799)]
kCAFillRuleEvenOdd : 奇偶原則。
通過(guò)從canvas上某個(gè)點(diǎn)往任一方向繪制射線到無(wú)窮遠(yuǎn),然后計(jì)算給定圖形上線段路徑和該射線交叉點(diǎn)的數(shù)量。如果這個(gè)數(shù)是奇數(shù),那么該點(diǎn)在圖形內(nèi)部;如果是偶數(shù),該點(diǎn)在圖形外部。
[圖片上傳失敗...(image-53b934-1552033143799)]
strokeColor:邊線顏色。lineDashPhase:邊線樣式的起始位置,即,如果lineDashPattern設(shè)置為@[2,2,3,4], lineDashPhase即為第一個(gè)長(zhǎng)度為2的線的起始位置。strokeStart,strokeEnd: [0,1]表示畫(huà)邊線的起點(diǎn)和終點(diǎn)。lineDashPattern: NSNumber數(shù)組,依次表示單個(gè)線的長(zhǎng)度和空白的長(zhǎng)度。
DEMO:
// 創(chuàng)建一個(gè)路徑對(duì)象
UIBezierPath *linePath = [UIBezierPath bezierPath];
// 起點(diǎn)
[linePath moveToPoint:(CGPoint){20,20}];
// 其他點(diǎn)
[linePath addLineToPoint:(CGPoint){180,160}];
[linePath addLineToPoint:(CGPoint){200,50}];
[linePath addLineToPoint:CGPointMake(250, 250)];
// 設(shè)置路徑畫(huà)布
CAShapeLayer *lineLayer = [CAShapeLayer layer];
lineLayer.bounds = (CGRect){0,0,200,200};
lineLayer.position = CGPointMake(100, 100);
lineLayer.lineWidth = 2.0;
lineLayer.strokeColor = [UIColor blueColor].CGColor; // 邊線顏色
lineLayer.path = linePath.CGPath;
lineLayer.fillColor = nil; // 默認(rèn)是black
// 添加到圖層上
[self.layer addSublayer:lineLayer];
更多Demo可見(jiàn)關(guān)于貝塞爾曲線與CAShapeLayer的學(xué)習(xí)
總結(jié):
UIBezierPath 在當(dāng)前的繪圖上下文中繪制圖形了. 因?yàn)閯?chuàng)建、 配置、 渲染路徑等操作, 都是完全不同的步驟, 所以你可以在你的代碼中非常容易的對(duì)UIBezierPath 對(duì)象進(jìn)行復(fù)用. 你甚至可以使用同一個(gè) UIBezierPath 對(duì)象去渲染同一個(gè)圖形很多次, 你也可以再多次渲染的間隔中, 修改屬性來(lái)渲染出不同樣式的路徑.
當(dāng)你為UIBezierPath 對(duì)象配置完幾何路徑和繪圖屬性之后, 你就可以使用stroke 和 fill方法在當(dāng)前的繪圖上下文中進(jìn)行繪制了. stroke方法將會(huì)使用當(dāng)前的strokeColor 和 繪圖屬性來(lái)描繪曲線的輪廓. 同樣的, fill 方法將會(huì)使用fillColor 來(lái)填充路徑所圍成的圖形(使用UIColor 類(lèi)方法來(lái)設(shè)置strokeColor 和 fillColor).
本文大量方法理解源于此文UIBezier--簡(jiǎn)書(shū), 感謝文章作者對(duì)UIBezier進(jìn)行了較為全面細(xì)致的分析,提供了大量有關(guān)官方文檔的譯解,使本人受益匪淺。
后續(xù)會(huì)繼續(xù)增進(jìn)有關(guān)UIBezierPath的深入理解及一些靈活運(yùn)用的實(shí)例,屆時(shí)會(huì)補(bǔ)充到本文中。