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 默認(rèn)值矢棚,
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繪制圖形線條艰垂,還有虛線,圖標(biāo)等翻伺,并進行簡單的動畫材泄。項目中會用來制作曲線!
更復(fù)雜的動畫也會說一些吨岭,比如QQ未讀消息的拖拽的動畫拉宗。

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旦事,一起剝皮案震驚了整個濱河市魁巩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姐浮,老刑警劉巖谷遂,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異卖鲤,居然都是意外死亡肾扰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門蛋逾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來集晚,“玉大人,你說我怎么就攤上這事区匣⊥蛋危” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵亏钩,是天一觀的道長莲绰。 經(jīng)常有香客問我,道長姑丑,這世上最難降的妖魔是什么蛤签? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮彻坛,結(jié)果婚禮上顷啼,老公的妹妹穿的比我還像新娘。我一直安慰自己昌屉,他們只是感情好钙蒙,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著间驮,像睡著了一般躬厌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竞帽,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天扛施,我揣著相機與錄音,去河邊找鬼屹篓。 笑死疙渣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堆巧。 我是一名探鬼主播妄荔,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泼菌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了啦租?” 一聲冷哼從身側(cè)響起哗伯,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎篷角,沒想到半個月后焊刹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡恳蹲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年虐块,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘉蕾。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡非凌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荆针,到底是詐尸還是另有隱情,我是刑警寧澤颁糟,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布航背,位于F島的核電站,受9級特大地震影響棱貌,放射性物質(zhì)發(fā)生泄漏玖媚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一婚脱、第九天 我趴在偏房一處隱蔽的房頂上張望今魔。 院中可真熱鬧,春花似錦障贸、人聲如沸错森。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩维。三九已至,卻和暖如春袁波,著一層夾襖步出監(jiān)牢的瞬間瓦阐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工篷牌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睡蟋,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓枷颊,卻偏偏與公主長得像戳杀,于是被迫代替她去往敵國和親该面。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容