你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS繪畫之UIBezierPath

iOS繪畫之UIBezierPath

編輯:IOS開發基礎


概述

UIBezierPath用於定義一個由直線/曲線組合而成的路徑, 並且可以在自定義視圖中渲染該路徑. 在使用的過程中, 我們只需要先指定好路徑的結構, 比如一條直線、一條貝塞爾曲線、一個矩形、一個橢圓、一個圓弧等, 然後使用系統為我們提供的方法將構建好的路徑渲染出來即可

UIBezierPath位於UIKit庫中, 是針對Core Graphics庫中的CGPathRef的封裝, 其已經可以幫助我們實現一般需求, 下面讓我們一起學習一下UIBezierPath的使用方法

注: 使用UIBezierPath繪畫的代碼寫在自定義視圖的drawRect:方法中

- (void)drawRect:(CGRect)rect
{
    // Drawing code
}

關於初始化

+ (instancetype)bezierPath

初始化一個UIBezierPath對象

UIBezierPath *path = [UIBezierPath bezierPath];
+ (instancetype)bezierPathWithRect:(CGRect)rect

以"矩形路徑"初始化一個UIBezierPath對象

// 參數一: 矩形范圍
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 200, 100)];
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect

以"內切於一個矩形的橢圓路徑"初始化一個UIBezierPath對象

// 參數一: 矩形范圍
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 200, 100)];
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius

以"圓角矩形路徑"初始化一個UIBezierPath對象

// 參數一: 矩形范圍 
// 參數二: 圓角半徑, 如果半徑大於矩形短邊的一半, 則按照一半處理
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 200, 100) cornerRadius:30];
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii

以"可選圓弧位置的圓角矩形路徑"初始化一個UIBezierPath對象

// 參數一: 矩形范圍
// 參數二: 圓弧位置, 可以多選
// 參數三: 圓弧半徑, 如果半徑大於矩形短邊的一半, 則按照一半處理, CGSize以小的為准(自己試的, 文檔沒說)
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 200, 100) byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(30, 50)];
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise

以"圓弧路徑"初始化一個UIBezierPath對象

// 參數一: 圓弧圓心
// 參數二: 圓弧半徑
// 參數三: 開始弧度
// 參數四: 結束弧度
// 參數五: 是否為順時針
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];

1598380-7e2ac3f4383ca480.jpeg

坐標系統

關於構造一個路徑

- (void)moveToPoint:(CGPoint)point

將當前點移動到指定的位置

UIBezierPath *path = [UIBezierPath bezierPath];
// 參數一: 指定的位置
[path moveToPoint:CGPointMake(20, 20)];
- (void)addLineToPoint:(CGPoint)point

在路徑中增加一條直線

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
// 參數一: 直線的終點位置
[path addLineToPoint:CGPointMake(100, 100)];
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise

在路徑中增加一條圓弧

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
[path addLineToPoint:CGPointMake(100, 20)];
// 參數一: 圓弧圓心
// 參數二: 圓弧半徑
// 參數三: 開始弧度
// 參數四: 結束弧度
// 參數五: 是否為順時針
[path addArcWithCenter:CGPointMake(60, 20) radius:40 startAngle:0 endAngle:M_PI clockwise:YES];
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint

在路徑中增加一條二次貝塞爾曲線

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
// 參數一: 曲線的終點位置
// 參數二: 控制點
[path addQuadCurveToPoint:CGPointMake(100, 20) controlPoint:CGPointMake(100, 60)];

1598380-1d4469a1b72e41b3.jpeg

二次貝塞爾曲線
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2

在路徑中增加一條三次貝塞爾曲線

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
// 參數一: 曲線的終點位置
// 參數二: 第一控制點
// 參數三: 第二控制點
[path addCurveToPoint:CGPointMake(100, 20) controlPoint1:CGPointMake(30, 60) controlPoint2:CGPointMake(100, 100)];

1598380-76ec483caf4fe78a.jpeg

三次貝塞爾曲線

關於路徑信息

@property(readonly,getter=isEmpty) BOOL empty

是否路徑信息為空, 即使通過moveToPoint:移動到指定的位置也算不為空

UIBezierPath *path = [UIBezierPath bezierPath];
BOOL isEmpty = path.empty;
@property(nonatomic,readonly) CGRect bounds

可以封閉所有路徑點的最小矩形范圍, 包括多次貝塞爾曲線的控制點在內

UIBezierPath *path = [UIBezierPath bezierPath];
CGRect bounds = path.bounds;
@property(nonatomic,readonly) CGPoint currentPoint

路徑當前所在點

UIBezierPath *path = [UIBezierPath bezierPath];
CGPoint currentPoint = path.currentPoint;
- (BOOL)containsPoint:(CGPoint)point

是否包含指定點

UIBezierPath *path = [UIBezierPath bezierPath];
BOOL isContainsPoint = [path containsPoint:CGPointMake(20, 30)];

關於路徑操作

- (void)closePath

使用一條直線閉合路徑的起點和終點, 該方法同時也會更新當前點到新直線的終點(即路徑的起點)

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 20)];
[path addLineToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(100, 200)];
[path closePath];
- (void)removeAllPoints

移除路徑中所有的點

UIBezierPath *path = [UIBezierPath bezierPath];
[path removeAllPoints];
- (void)appendPath:(UIBezierPath *)bezierPath

路徑中增加一個已有路徑

UIBezierPath *path = [UIBezierPath bezierPath];
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path appendPath:path2];
- (UIBezierPath *)bezierPathByReversingPath

返回一個翻轉已有路徑的新路徑

UIBezierPath *path = [UIBezierPath bezierPath];
UIBezierPath *path2 = [path bezierPathByReversingPath];

關於繪圖

- (void)fill

利用當前繪畫屬性填充路徑封閉范圍, 該方法在繪畫之前會自動將開放子路徑封閉, 填充部分不包含路徑本身, 所以對於線寬較大的路徑, 填充部分會跟部分路徑重合

UIBezierPath *path = [UIBezierPath bezierPath];
// do something....
[path fill];
- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha

利用指定模式填充路徑封閉范圍, 該方法在繪畫之前會自動將開放子路徑封閉, 填充部分不包含路徑本身, 所以對於線寬較大的路徑, 填充部分會跟部分路徑重合

UIBezierPath *path = [UIBezierPath bezierPath];
// do something....
[path fillWithBlendMode:kCGBlendModeNormal alpha:0.8];
- (void)stroke

利用當前繪畫屬性沿著路徑畫線

UIBezierPath *path = [UIBezierPath bezierPath];
// do something....
[path stroke];
- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha

利用指定模式沿著路徑畫線

UIBezierPath *path = [UIBezierPath bezierPath];
// do something....
[path strokeWithBlendMode:kCGBlendModeNormal alpha:0.8];

關於繪畫屬性

@property(nonatomic) CGFloat lineWidth

路徑的線寬

UIBezierPath *path = [UIBezierPath bezierPath];
path.lineWidth = 10;
- (void)setFill

路徑的填充顏色

[[UIColor orangeColor] setFill];
- (void)setStroke

路徑的畫線顏色

[[UIColor orangeColor] setStroke];
@property(nonatomic) CGLineCap lineCapStyle

路徑的終點形狀, 該屬性適用於開放路徑的起點和終點, 默認為kCGLineCapButt(方形結束, 結束位置正好為精確位置), 其他可選項為kCGLineCapRound(圓形結束, 結束位置超過精確位置半個線寬)和kCGLineCapSquare(方形結束, 結束位置超過精確位置半個線寬)

UIBezierPath *path = [UIBezierPath bezierPath];
path.lineCapStyle = kCGLineCapButt;
@property(nonatomic) CGLineJoin lineJoinStyle

路徑的連接點形狀, 默認為kCGLineJoinMiter(全部連接), 其他可選項為kCGLineJoinRound(圓形連接)和kCGLineJoinBevel(斜角連接)

UIBezierPath *path = [UIBezierPath bezierPath];
path.lineJoinStyle = kCGLineJoinMiter;

關於二維形變

- (void)applyTransform:(CGAffineTransform)transform

對路徑中的所有點進行二維形變, 該變化立即生效, 且為永久性改變所有點

UIBezierPath *path = [UIBezierPath bezierPath];
[path applyTransform:CGAffineTransformMakeTranslation(20, 20)];

示例

以"今日頭條下拉刷新效果"為例, 練習一下繪畫方式

CGAffineTransform transform = CGAffineTransformMakeTranslation((self.bounds.size.width-50*5)/2, 100);
transform = CGAffineTransformScale(transform, 5, 5);

UIBezierPath *path1 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 50, 50) cornerRadius:10];
[path1 applyTransform:transform];
[[UIColor colorWithRed:198/255.0f green:198/255.0f blue:198/255.0f alpha:1.0f] setStroke];
[path1 stroke];

UIBezierPath *path2 = [UIBezierPath bezierPathWithRect:CGRectMake(7, 10, 14, 12)];
[path2 applyTransform:transform];
[[UIColor colorWithRed:224/255.0f green:224/255.0f blue:224/255.0f alpha:1.0f] setFill];
[path2 fill];

UIBezierPath *path3 = [UIBezierPath bezierPathWithRect:CGRectMake(7, 10, 14, 12)];
[path3 applyTransform:transform];
[[UIColor colorWithRed:189/255.0f green:189/255.0f blue:189/255.0f alpha:1.0f] setStroke];
[path3 stroke];

UIBezierPath *path11 = [UIBezierPath bezierPath];
[path11 moveToPoint:CGPointMake(28, 10)];
[path11 addLineToPoint:CGPointMake(43, 10)];
[path11 applyTransform:transform];
[[UIColor colorWithRed:153/255.0f green:153/255.0f blue:153/255.0f alpha:1.0f] setStroke];
[path11 stroke];

UIBezierPath *path12 = [UIBezierPath bezierPath];
[path12 moveToPoint:CGPointMake(28, 16)];
[path12 addLineToPoint:CGPointMake(43, 16)];
[path12 applyTransform:transform];
[path12 stroke];

UIBezierPath *path13 = [UIBezierPath bezierPath];
[path13 moveToPoint:CGPointMake(28, 22)];
[path13 addLineToPoint:CGPointMake(43, 22)];
[path13 applyTransform:transform];
[path13 stroke];

UIBezierPath *path21 = [UIBezierPath bezierPath];
[path21 moveToPoint:CGPointMake(7, 28)];
[path21 addLineToPoint:CGPointMake(43, 28)];
[path21 applyTransform:transform];
[path21 stroke];

UIBezierPath *path22 = [UIBezierPath bezierPath];
[path22 moveToPoint:CGPointMake(7, 34)];
[path22 addLineToPoint:CGPointMake(43, 34)];
[path22 applyTransform:transform];
[path22 stroke];

UIBezierPath *path23 = [UIBezierPath bezierPath];
[path23 moveToPoint:CGPointMake(7, 40)];
[path23 addLineToPoint:CGPointMake(43, 40)];
[path23 applyTransform:transform];
[path23 stroke];

1598380-5205dd8677fbbde6.png

今日頭條示例
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved