你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> UIBezierPath詳解

UIBezierPath詳解

編輯:IOS開發綜合

使用UIBezierPath類可以創建基於矢量的路徑,這個類在UIKit中。此類是Core Graphics框架關於path的一個封裝。使用此類可以定義簡單的形狀,如橢圓或者矩形,或者有多個直線和曲線段組成的形狀。

Bezier Path 基礎 UIBezierPath對象是CGPathRef數據類型的封裝。path如果是基於矢量形狀的,都用直線和曲線段去創建。我們使用直線段去創建矩形和多邊形,使用曲線段去創建弧(arc),圓或者其他復雜的曲線形狀。每一段都包括一個或者多個點,繪圖命令定義如何去诠釋這些點。每一個直線段或者曲線段的結束的地方是下一個的開始的地方。每一個連接的直線或者曲線段的集合成為subpath。一個UIBezierPath對象定義一個完整的路徑包括一個或者多個subpaths。   UIBezierPath類頭文件定義

// 根據一個Rect 畫一個矩形曲線

+ (instancetype)bezierPath;

 

/**

* 根據一個Rect 畫一個橢圓曲線 Rect為正方形時 畫的是一個圓

* @param rect CGRect一個矩形

*/

+ (instancetype)bezierPathWithRect:(CGRect)rect;

/**

* 根據一個Rect 畫一個圓角矩形曲線 (Radius:圓角半徑) 當Rect為正方形時且Radius等於邊長一半時 畫的是一個圓

* @param rect CGRect一個矩形

*/

+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;

/**

* 根據一個Rect 畫一個圓角矩形曲線 當Rect為正方形時且Radius等於邊長一半時 畫的是一個圓

* @param rect CGRect一個矩形

* @param cornerRadius 圓角半徑

*/

+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;

typedef NS_OPTIONS(NSUInteger, UIRectCorner) {

UIRectCornerTopLeft = 1 << 0,

UIRectCornerTopRight = 1 << 1,

UIRectCornerBottomLeft = 1 << 2,

UIRectCornerBottomRight = 1 << 3,

UIRectCornerAllCorners = ~0UL

};

/**

* 根據一個Rect 針對四角中的某個或多個角設置圓角

*

* @param rect CGRect一個矩形

* @param corners 允許指定矩形的部分角為圓角,而其余的角為直角,取值來自枚舉

* @param cornerRadii 指定了圓角的半徑,這個參數的取值是 CGSize 類型,也就意味著這裡需要給出的是橢圓的半徑。

*/

+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;

 

/**

* 以某個中心點畫弧線

* @param center 指定了圓弧所在正圓的圓心點坐標

* @param radius 指定了圓弧所在正圓的半徑

* @param startAngle 指定了起始弧度位置 注意: 起始與結束這裡是弧度

* @param endAngle 指定了結束弧度位置

* @param clockwise 指定了繪制方向,以時鐘方向為判斷基准 看下圖

*/

+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

\圖片來自網絡

 

 

/**

* 根據CGPath創建並返回一個新的UIBezierPath對象

* @param CGPath CGPathRef

*/

+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;

@property(nonatomic) CGPathRef CGPath;

- (CGPathRef)CGPath NS_RETURNS_INNER_POINTER CF_RETURNS_NOT_RETAINED;

/**

* 設置第一個起始點到接收器

* @param point 起點坐標

*/

- (void)moveToPoint:(CGPoint)point;

 

/**

* 附加一條直線到接收器的路徑

* @param point 要到達的坐標

*/

- (void)addLineToPoint:(CGPoint)point;

 

/**

* 該方法就是畫三次貝塞爾曲線的關鍵方法,以三個點畫一段曲線,一般和moveToPoint:配合使用。其實端點為moveToPoint:設置,終止端點位為endPoint;。控制點1的坐標controlPoint1,這個參數可以調整。控制點2的坐標是controlPoint2。

*

* @param endPoint 終點坐標

* @param controlPoint1 控制點1

* @param controlPoint2 控制點2 看下圖

*/

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

\圖片來自網絡

 

 

/**

* 畫二次貝塞爾曲線,是通過調用此方法來實現的。一般和moveToPoint:配合使用。endPoint終端點,controlPoint控制點,對於二次貝塞爾曲線,只有一個控制點

* @param endPoint 終點坐標

* @param controlPoint 控制點 看下圖

*/

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

\圖片來自網絡

 

 

/**

* 添加一個弧線 與bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:區別是bezierPathWithArcCenter它是初始化一個弧線,addArcWithCenter是添加一個弧線,共同點就是參數都一樣

* @param center 指定了圓弧所在正圓的圓心點坐標

* @param radius 指定了圓弧所在正圓的半徑

* @param startAngle 指定了起始弧度位置

* @param endAngle 指定了結束弧度位置

* @param clockwise 指定了繪制方向,以時鐘方向為判斷基准

*/

- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);

 

/**

* 閉合線 使用這個方法起始點與終點將相連

*/

- (void)closePath;

 

/**

* 移除所有坐標點

*/

- (void)removeAllPoints;

 

// Appending paths

// 添加一個paths UIBezierPath

- (void)appendPath:(UIBezierPath *)bezierPath;

 

// Modified paths

// 創建 並返回一個與當前路徑相反的新的貝塞爾路徑對象

- (UIBezierPath *)bezierPathByReversingPath NS_AVAILABLE_IOS(6_0);

 

// Transforming paths

// 用指定的仿射變換矩陣變換路徑的所有點

- (void)applyTransform:(CGAffineTransform)transform;

 

// Path info

// 該值指示路徑是否有任何有效的元素。

@property(readonly,getter=isEmpty) BOOL empty;

// 路徑包括的矩形

@property(nonatomic,readonly) CGRect bounds;

// 圖形路徑中的當前點

@property(nonatomic,readonly) CGPoint currentPoint;

// 接收器是否包含指定的點

- (BOOL)containsPoint:(CGPoint)point;

 

// Drawing properties

// 線寬

@property(nonatomic) CGFloat lineWidth;

 

typedef CF_ENUM(int32_t, CGLineCap) {

kCGLineCapButt, 默認的

kCGLineCapRound, 輕微圓角

kCGLineCapSquare 正方形

};

// 端點類型

@property(nonatomic) CGLineCap lineCapStyle;

 

typedef CF_ENUM(int32_t, CGLineJoin) {

kCGLineJoinMiter, 默認的表示斜接

kCGLineJoinRound, 圓滑銜接

kCGLineJoinBevel 斜角連接

};

// 連接類型

@property(nonatomic) CGLineJoin lineJoinStyle;

 

// 最大斜接長度 斜接長度指的是在兩條線交匯處內角和外角之間的距離

@property(nonatomic) CGFloat miterLimit; // Used when lineJoinStyle is kCGLineJoinMiter

\

/*

最大斜接長度 斜接長度指的是在兩條線交匯處內角和外角之間的距離

只有lineJoin屬性為kCALineJoinMiter時miterLimit才有效

邊角的角度越小,斜接長度就會越大。

為了避免斜接長度過長,我們可以使用 miterLimit 屬性。

如果斜接長度超過 miterLimit 的值,邊角會以 lineJoin的 "bevel"即kCALineJoinBevel類型來顯示

*/

\

 

// 確定彎曲路徑短的繪制精度的因素

@property(nonatomic) CGFloat flatness;

// 一個bool值 指定even-odd規則是否在path可用

@property(nonatomic) BOOL usesEvenOddFillRule; // Default is NO. When YES, the even-odd fill rule is used for drawing, clipping, and hit testing.

// 設置線型

- (void)setLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase;

// 檢索線型

- (void)getLineDash:(nullable CGFloat *)pattern count:(nullable NSInteger *)count phase:(nullable CGFloat *)phase;

 

// Path operations on the current graphics context 當前圖形上下文中的路徑操作:

// 填充顏色

- (void)fill;

 

// 利用當前繪圖屬性沿著接收器的路徑繪制

- (void)stroke;

 

// These methods do not affect the blend mode or alpha of the current graphics context

// 用指定的混合模式和透明度值來描繪受接收路徑所包圍的區域

- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

 

// 使用指定的混合模式和透明度值沿著接收器路徑。繪制一行

- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

 

// 剪切被接收者路徑包圍的區域 該路徑是帶有剪切路徑的當前繪圖上下文。使得其成為我們當前的剪切路徑

- (void)addClip;

 

實踐~敲出如下圖代碼

\

- (void)drawRect:(CGRect)rect {

 

UIColor *brushColor = [UIColor whiteColor];

 

// 根據一個Rect 畫一個矩形曲線

UIBezierPath *rectangular = [UIBezierPath bezierPathWithRect:CGRectMake(5, 5, 30, 30)];

[PNRed set];

[rectangular fill];

[brushColor set];

[rectangular stroke];

 

// 根據一個Rect 畫一個橢圓曲線 Rect為正方形時 畫的是一個圓

UIBezierPath *oval = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 5, 50, 30)];

[PNBlue set];

[oval fill];

[brushColor set];

[oval stroke];

 

// 根據一個Rect 畫一個圓角矩形曲線 (Radius:圓角半徑) 當Rect為正方形時且Radius等於邊長一半時 畫的是一個圓

UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(95, 5, 40, 30) cornerRadius:5];

[PNStarYellow set];

[roundedRect fill];

[brushColor set];

[roundedRect stroke];

 

// 根據一個Rect 針對四角中的某個或多個角設置圓角

UIBezierPath *roundedRect2 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(140, 5, 40, 30) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 50)];

[PNFreshGreen set];

[roundedRect2 fill];

[brushColor set];

[roundedRect2 stroke];

 

// 以某個中心點畫弧線

UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 15) radius:20 startAngle:0 endAngle:degreesToRadian(90) clockwise:YES];

[brushColor set];

[arcPath stroke];

 

// 添加一個弧線

UIBezierPath *arcPath2 = [UIBezierPath bezierPath];

[arcPath2 moveToPoint:CGPointMake(230, 30)];

[arcPath2 addArcWithCenter:CGPointMake(265, 30) radius:25 startAngle:degreesToRadian(180) endAngle:degreesToRadian(360) clockwise:YES];

// 添加一個UIBezierPath

[arcPath2 appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(265, 30) radius:20 startAngle:0 endAngle:M_PI*2 clockwise:YES]];

[PNStarYellow set];

[arcPath2 stroke];

 

// 根據CGPath創建並返回一個新的UIBezierPath對象

UIBezierPath *be = [self bezierPathWithCGPath];

[PNRed set];

[be stroke];

 

// 三角形

UIBezierPath *triangle = [UIBezierPath bezierPath];

[triangle moveToPoint:CGPointMake(145, 165)];

[triangle addLineToPoint:CGPointMake(155, 185)];

[triangle addLineToPoint:CGPointMake(135, 185)];

[PNStarYellow set];

[triangle fill];

// [triangle stroke];

[triangle closePath];

 

// 二次貝塞爾曲線

UIBezierPath *quadBe = [UIBezierPath bezierPath];

[quadBe moveToPoint:CGPointMake(30, 150)];

[quadBe addQuadCurveToPoint:CGPointMake(130, 150) controlPoint:CGPointMake(30, 70)];

 

UIBezierPath *quadBe2 = [UIBezierPath bezierPath];

[quadBe2 moveToPoint:CGPointMake(160, 150)];

[quadBe2 addQuadCurveToPoint:CGPointMake(260, 150) controlPoint:CGPointMake(210, 50)];

[quadBe2 appendPath:quadBe];

quadBe2.lineWidth = 1.5f;

quadBe2.lineCapStyle = kCGLineCapSquare;

quadBe2.lineJoinStyle = kCGLineJoinRound;

[brushColor set];

[quadBe2 stroke];

 

// 三次貝塞爾曲線

UIBezierPath *threePath = [UIBezierPath bezierPath];

[threePath moveToPoint:CGPointMake(30, 250)];

[threePath addCurveToPoint:CGPointMake(260, 230) controlPoint1:CGPointMake(120, 180) controlPoint2:CGPointMake(150, 260)];

threePath.lineWidth = 1.5f;

threePath.lineCapStyle = kCGLineCapSquare;

threePath.lineJoinStyle = kCGLineJoinRound;

[brushColor set];

[threePath stroke];

}

 

- (UIBezierPath *)bezierPathWithCGPath {

UIBezierPath *framePath;

CGFloat arrowWidth = 14;

 

CGMutablePathRef path = CGPathCreateMutable();

 

CGRect rectangle = CGRectInset(CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetWidth(self.bounds)), 3,3);

 

CGPoint p[3] = {

 

{CGRectGetMidX(self.bounds)-arrowWidth/2, CGRectGetWidth(self.bounds)-6},

 

{CGRectGetMidX(self.bounds)+arrowWidth/2, CGRectGetWidth(self.bounds)-6},

 

{CGRectGetMidX(self.bounds), CGRectGetHeight(self.bounds)-4}

 

};

 

CGPathAddRoundedRect(path, NULL, rectangle, 5, 5);

 

CGPathAddLines(path, NULL, p, 3);

 

CGPathCloseSubpath(path);

// 根據CGPath創建並返回一個新的UIBezierPath對象

framePath = [UIBezierPath bezierPathWithCGPath:path];

 

CGPathRelease(path);

 

return framePath;

}

下載源代碼
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved