iOS-貝塞爾曲線(UIBezierPath)的基本使用

UIBezierPathUIKitCore Graphics框架中的一個類,使用UIBezierPath可以繪制各種簡單的圖形。

iOS-貝塞爾曲線(UIBezierPath)的基本使用
iOS-貝塞爾曲線(UIBezierPath)詳解(CAShapeLayer)
iOS-UIBezierPath動畫之果凍動畫
iOS-CGContextRef開啟上下文繪圖

今天我們簡單介紹一下它的使用方法:
  • UIBezierPath的基本使用方法以及概念
  • 各種圖形的繪制:直線,折線,多邊形,圓,圓弧,虛線....等等
  • 延伸場景:動畫,圖表.....等

UIBezierPath的基本使用方法

首先繪制圖形線條要在view- (void)drawRect:(CGRect)rect方法中。
先寫一個簡單的例子,來介紹幾個常用的方法屬性。

- (void)drawRect:(CGRect)rect {
    // Drawing code
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(30, 30)];
    [path addLineToPoint:CGPointMake(200, 80)];
    [path addLineToPoint:CGPointMake(150, 150)];

    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //終點處理
    path.lineJoinStyle = kCGLineJoinRound; //線條拐角
    
    [path stroke];  
}

效果圖如下:


折線

在我們繪制之前,我們先簡單了解一下UIBezierPath的幾個屬性和方法:
1、[color set]設(shè)置線條顏色
2、path.lineWidth = 4.0設(shè)置線條的寬度
3、path.lineCapStyle設(shè)置起點和終點的樣式,是一個枚舉值:

1、kCGLineCapButt 默認值,
2、kCGLineCapRound 圓形端點
3、 kCGLineCapSquare 方形端點

4、path.lineJoinStyle設(shè)置連接點的樣式,是一個枚舉值。

1、kCGLineJoinMiter 斜接連接處是一個斜線,
2、kCGLineJoinRound 連接處是一段圓滑的弧度,
3、kCGLineJoinBevel 一段斜角連接

至于具體的樣式,大家可以看看效果。
5、[path stroke]用stroke畫出來的不是被填充的view,與此對應(yīng)的[path fill]得到的是內(nèi)部被填充的view。
6、moveToPoint:設(shè)置起始點
7、addLineToPoint:連線到另一個點。(其實我們繪制圖形就是,把很多個點連接起來,主要就是依靠這個方法)
8、closePath這個方法就是最后一條線,將終點和起點連接起來。

接下來我們開始學(xué)習(xí)一些基本使用

?? ?? ?? ?? ?? ??

1. 繪制多邊形
//多邊形
- (void)drawRect:(CGRect)rect {
    // Drawing code
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(50, 100)];
    [path addLineToPoint:CGPointMake(150, 50)];
    [path addLineToPoint:CGPointMake(250, 100)];
    [path addLineToPoint:CGPointMake(250, 200)];
    [path addLineToPoint:CGPointMake(100, 200)];
    [path closePath]; // 最后一根線條,可以直接調(diào)此方法
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //終點處理
    path.lineJoinStyle = kCGLineJoinRound; //線條拐角
    
  [path stroke];  //不填充
  // [path fill];  //填充
}

效果圖如下:


多邊形

如果將上面代碼中,最后的[path stroke]方法改為[path fill],那么圖形就會被填充顏色

填充多邊形
2. 矩形

矩形的繪制,可以使用上面繪制多邊形的方法去繪制(方法1)。
正方形是特殊的矩形,使用原理相同。只要把寬和高設(shè)置一樣即可。

UIBezierPath類提供了特殊的方法可以直接繪制矩形。
即:+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect

使用方法如下:

//矩形
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 150, 80)];
    
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //終點處理
    path.lineJoinStyle = kCGLineJoinRound; //線條拐角
    
    [path stroke];
}

效果圖如下:


矩形
3. 圓和橢圓

圓形和橢圓形的繪制,如同矩形一樣,UIBezierPath類提供了直接繪制的方法:+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect。傳入的rect參數(shù)是一個長方形就會得到一個內(nèi)切的橢圓,傳入的是一個正方形得到的就是一個內(nèi)切的圓形。

使用方法如下:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    UIColor *color = [UIColor redColor];
    [color set];
    
    UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 150, 80)];
    path.lineWidth = 5.0;
    
    [path stroke];
}

效果圖如下:


橢圓
4. 一段圓弧

使用+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;方法可以得到一單圓弧。

/// 創(chuàng)建一段圓弧
/// @param center 圓弧的原點(中心點)
/// @param radius 半徑
/// @param startAngle 其實角度
/// @param endAngle 結(jié)束角度
/// @param clockwise 是否是順時針
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

使用方法如下:


//圓弧
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set];
    
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:100 startAngle:1.25 * M_PI endAngle:1.75 * M_PI clockwise:YES];
    [path addLineToPoint:CGPointMake(200, 200)];
    [path closePath];
    
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //終點處理
    path.lineJoinStyle = kCGLineJoinRound; //線條拐角
    [path stroke];
}

效果圖如下:


圓弧
5. 繪制二次曲線

繪制二次曲線,我們先明白一個概念:
二次曲線就是一段曲線,圓弧是比較特殊的曲線,暫不考慮。
每個二次曲線的的起始點和終點的切線,會相交到一個點,我們稱之為:控制點。
繪制二次曲線我們需要三個點:起始點、控制點、終點。
如下圖所示:


控制點

使用方法如下:

//二次曲線
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(100, 200)];
    [path addQuadCurveToPoint:CGPointMake(250, 200) controlPoint:CGPointMake(50, 40)];
   
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    
    [path stroke];
}

效果圖如下:


二次曲線
6. 繪制三次曲線

三次曲線和二次曲線類似,原理相同。
簡單地說,我們需要起始點、終點、兩個控制點。
因為是三次曲線,有兩個波,一個波峰一個波谷,所以需要兩個控制點。

需要用到方法:- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

使用方法如下:

// 三次曲線
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(50, 150)];
    [path addCurveToPoint:CGPointMake(260, 150) controlPoint1:CGPointMake(140, 0) controlPoint2:CGPointMake(140, 400)];

    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    
    [path stroke];
}

效果圖如下:


三次曲線
7. 畫帶圓角的矩形

這個結(jié)果類似于講一個矩形切圓角,但是不一樣。
這是一條線。切圓角的矩形線!

使用系統(tǒng)提供的方法:+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius即可。繪制一個帶內(nèi)切圓的矩形。

使用方法如下:

//帶內(nèi)切角的矩形
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 200, 150) cornerRadius:20];
    
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //線條拐角
    path.lineJoinStyle = kCGLineJoinRound; //終點處理
    
    [path stroke];
}

效果圖如下:


帶內(nèi)切角的矩形

如果想指定內(nèi)切某一個角,系統(tǒng)也提供了方法。
使用方法如下:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 200, 150) byRoundingCorners:UIRectCornerTopRight cornerRadii:CGSizeMake(20, 20)];
    
    path.lineWidth = 5.0;
    path.lineCapStyle = kCGLineCapRound; //線條拐角
    path.lineJoinStyle = kCGLineJoinRound; //終點處理
    
    [path stroke];
}

效果圖如下:


內(nèi)切右上角
8. 虛線

虛線我們在項目中會用到,但是這種方法卻比較冷門。系統(tǒng)提供了一個方法:- (void)setLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase;

這個方法中有一個參數(shù)比較特殊,即:(nullable const CGFloat *)pattern
該屬性是一個 C 語言的數(shù)組, 其中每一個元素都是 CGFloat

  1. 數(shù)組中的元素代表著線段某一部分的長度, 第一個元素代表線段的第一條線
  2. 第二個元素代表線段中的第一個間隙

我們舉個例子: 聲明一個數(shù)組 CGFloat dash[] = @{5.0, 2.0};
這表示繪制的虛線的第一部分長度為5.0, 第一個間隙長度為2.0。 虛線的第二部分長度為5.0, 第二個間隙長度為2.0. 以此類推.
count表示參數(shù)pattern的個數(shù)
phase表示從第幾個像素點開始繪制。

使用方法:

//虛線
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIColor *color = [UIColor redColor];
    [color set]; //設(shè)置線條顏色
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(100, 80)];
    [path addLineToPoint:CGPointMake(350, 120)];
    path.lineWidth = 2;

    CGFloat dash[] = {8.0,3.0,16.0,7.0};
    [path setLineDash:dash count:4 phase:7];
    [path stroke];
}

效果圖如下:


虛線

9. 更新繪圖

如果想更新貝塞爾曲線圖,就要重新繪制,或者重新調(diào)用- (void)drawRect:(CGRect)rect。

系統(tǒng)提供了專門的方法,來重新繪制

[self setNeedsDisplay];

調(diào)用此方法,就可以重繪!

總結(jié):

從全篇看下來你會發(fā)現(xiàn),其實就是介紹了幾個系統(tǒng)提供的幾個方法的使用簡介。這都是最起初的使用,都是在view的內(nèi)部的方法drawRect里面進行繪制。
一般項目用到的不多,后面會說結(jié)合CAShapeLayer,在外部對已有的view繪制圖形線條,還有虛線,圖標等,并進行簡單的動畫。項目中會用來制作曲線!
更復(fù)雜的動畫也會說一些,比如QQ未讀消息的拖拽的動畫。

本篇文章部分代碼借鑒了劉光軍_Shine的文章,這是原文章地址

所有代碼我都全部敲寫驗證過。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容