iOS UIBezierPath貝塞爾曲線常用方法

關(guān)于 UIBezierPath

UIBezierPath這個類在UIKit中拯刁, 是Core Graphics框架關(guān)于path的一個封裝捂人,使用此類可以定義簡單的形狀鸟款,比如我們常用到蓝谨,矩形灌具,圓形,橢圓譬巫,弧咖楣,或者不規(guī)則的多邊形

UIBezierPath 基本使用方法

UIBezierPath對象是CGPathRef數(shù)據(jù)類型的封裝。path如果是基于矢量形狀的芦昔,都用直線或曲線去創(chuàng)建诱贿。我們一般使用UIBezierPath都是在重寫view的drawRect方法這種情形。我們用直線去創(chuàng)建矩形或多邊形咕缎,使用曲線創(chuàng)建弧或者圓珠十。創(chuàng)建和使用path對象步驟:
1、 重寫View的drawRect方法
2凭豪、 創(chuàng)建UIBezierPath的對象
3焙蹭、 使用方法moveToPoint: 設(shè)置初始點
4、 根據(jù)具體要求使用UIBezierPath類方法繪圖(比如要畫線嫂伞、矩形孔厉、圓拯钻、弧烟馅?等)
5说庭、 設(shè)置UIBezierPath對象相關(guān)屬性 (比如lineWidth然磷、lineJoinStyle郑趁、aPath.lineCapStylecolor
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; //線條拐角
    path.lineJoinStyle = kCGLineJoinRound; //終點處理
    
    [path stroke];
}

其他基本使用方法

在介紹其他使用方法之前寡润,我們先來看一下 path的幾個屬性,以便下面我進(jìn)行設(shè)置舅柜。
1梭纹、[color set];設(shè)置線條顏色,也就是相當(dāng)于畫筆顏色
2致份、path.lineWidth = 5.0;這個很好理解了变抽,就是劃線的寬度
3、path.lineCapStyle這個線段起點是終點的樣式氮块,這個樣式有三種:

1绍载、kCGLineCapButt該屬性值指定不繪制端點, 線條結(jié)尾處直接結(jié)束滔蝉。這是默認(rèn)值击儡。
2、kCGLineCapRound 該屬性值指定繪制圓形端點蝠引, 線條結(jié)尾處繪制一個直徑為線條寬度的半圓阳谍。
3、kCGLineCapSquare 該屬性值指定繪制方形端點螃概。 線條結(jié)尾處繪制半個邊長為線條寬度的正方形矫夯。需要說明的是,這種形狀的端點與“butt”形狀的端點十分相似吊洼,只是采用這種形式的端點的線條略長一點而已


4训貌、path.lineJoinStyle這個屬性是用來設(shè)置兩條線連結(jié)點的樣式,同樣它也有三種樣式供我們選擇
(
1融蹂、kCGLineJoinMiter 斜接
2旺订、kCGLineJoinRound 圓滑銜接
3、kCGLineJoinBevel 斜角連接

5超燃、[path stroke];用 stroke 得到的是不被填充的 view 区拳,[path fill]; 用 fill 得到的內(nèi)部被填充的 view,這點在下面的代碼還有繪制得到的圖片中有意乓,可以體會一下這兩者的不同樱调。

繪制多邊形
duobianxing.png

繪制多邊形约素,實際上就是又一些直線條連成,主要使用moveToPoint:addLineToPoint:方法去創(chuàng)建笆凌,moveToPoint:這個方法是設(shè)置起始點圣猎,意味著從這個點開始,我們就可以使用addLineToPoint:去設(shè)置我們想要創(chuàng)建的多邊形經(jīng)過的點乞而,也就是兩線相交的那個點送悔,用addLineToPoint:去創(chuàng)建一個形狀的線段,我們可以連續(xù)創(chuàng)建line爪模,每一個line的起點都是先前的終點欠啤,終點就是指定的點,將線段連接起來就是我們想要創(chuàng)建的多邊形了屋灌。


#import "DrawPolygonView.h"

@implementation DrawPolygonView

- (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; //終點處理
    
    [path moveToPoint:CGPointMake(200.0, 50.0)];//起點
    
    // 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)點連線
    [path fill];//顏色填充
    
}

在這里我們可以看到最后第五條線是用[path closePath];得到的洁段,closePath方法不僅結(jié)束一個shape的subpath表述,它也在最后一個點和第一個點之間畫一條線段共郭,這個一個便利的方法我們不需要去畫最后一條線了祠丝, 哈哈哈哈。這里我們用到的是[path fill];//顏色填充進(jìn)行坐標(biāo)連點除嘹,但是我們看見的是五邊形內(nèi)部被顏色填充了写半, 如果我們使用[path stroke];那我們得到的就是一個用線畫的五邊形。

畫矩形或者正方形

juxing.png

大家都知道正方形就是特殊的矩形咯憾赁,不多講污朽。只說矩形。
使用+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect這個方法龙考,設(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; //終點處理
    
    [path stroke];
}
創(chuàng)建圓形或者橢圓形

yuanxing.png

使用+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect這個方法創(chuàng)建圓形或者橢圓形炎功。
傳入的rect矩形參數(shù)繪制一個內(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這個方法創(chuàng)建一段弧線,介紹一下這個方法中的參數(shù):

/*
 ArcCenter: 原點
 radius: 半徑
 startAngle: 開始角度
 endAngle: 結(jié)束角度
 clockwise: 是否順時針方向
 */

弧線的參考系:

arc.png
繪制二次貝塞爾曲線

erciquxian.png

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

oneControl.png
- (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];
}
繪制三次貝塞爾曲線
sanciquxian.png

使用這個方法繪制三次貝塞爾曲線

- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2  
Parameters 

這個方法繪制三次貝塞爾曲線。曲線段在當(dāng)前點開始居灯,在指定的點結(jié)束祭务,兩個控制點的切線定義内狗。下圖顯示了兩種曲線類型的相似,以及控制點和curve形狀的關(guān)系:


twoControl.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];
}
畫帶圓角的矩形

daiyuanjuxing.png

使用+ (instancetype)bezierPathWithRect:(CGRect)rect;這個方法繪制义锥,這個方法和bezierPathWithRect:類似柳沙,繪制一個帶內(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; //終點處理
    
    [path stroke];
}
指定矩形的某個角為圓角

yuanjiaojuxing.png

使用+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
這個方法繪制拌倍。參數(shù)的意思:rect 繪制矩形的 frame赂鲤,corners指定使哪個角為圓角,圓角類型為:

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];
}

小結(jié):

以上列舉的這幾種使用貝塞爾曲線繪制圖形的方法就是我們在開發(fā)中經(jīng)常能遇到的蛤袒。當(dāng)然這塊并沒有這么簡單熄云,還有結(jié)合 CAShapeLayer 進(jìn)行自定義動畫等等膨更,有時間會再寫一篇相關(guān)知識的總結(jié)。最后拉上我寫的這些方法匯合成的小 demo 供大家體會缴允。
鏈接:https://github.com/irembeu/UIBezierPathMethodsDemo.git
我的個人博客:
https://irembeu.github.io

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荚守,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子练般,更是在濱河造成了極大的恐慌矗漾,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薄料,死亡現(xiàn)場離奇詭異敞贡,居然都是意外死亡,警方通過查閱死者的電腦和手機摄职,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門誊役,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谷市,你說我怎么就攤上這事蛔垢。” “怎么了迫悠?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵鹏漆,是天一觀的道長。 經(jīng)常有香客問我创泄,道長艺玲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任鞠抑,我火速辦了婚禮饭聚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碍拆。我一直安慰自己若治,他們只是感情好慨蓝,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著端幼,像睡著了一般礼烈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上婆跑,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天此熬,我揣著相機與錄音,去河邊找鬼滑进。 笑死犀忱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扶关。 我是一名探鬼主播阴汇,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼节槐!你這毒婦竟也來了搀庶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤铜异,失蹤者是張志新(化名)和其女友劉穎哥倔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揍庄,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡咆蒿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蚂子。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沃测。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缆镣,靈堂內(nèi)的尸體忽然破棺而出芽突,到底是詐尸還是另有隱情,我是刑警寧澤董瞻,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布寞蚌,位于F島的核電站,受9級特大地震影響钠糊,放射性物質(zhì)發(fā)生泄漏挟秤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一抄伍、第九天 我趴在偏房一處隱蔽的房頂上張望艘刚。 院中可真熱鬧,春花似錦截珍、人聲如沸攀甚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秋度。三九已至曲秉,卻和暖如春带猴,著一層夾襖步出監(jiān)牢的瞬間积担,已是汗流浹背霉颠。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留事期,地道東北人滥壕。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像兽泣,于是被迫代替她去往敵國和親绎橘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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