iOS,貝塞爾曲線(UIBezierPath)


1.UIBezierPath簡介

2.UIBezierPath方法和屬性

3.UIBezierPath使用方式

UIBezierPath簡介

  使用UIBezierPath類可以創建基於矢量的路徑,這個類在UIKit中。此類是Core Graphics框架關於path的一個封裝, UIBezierPath對象是CGPathRef數據類型的封裝。。用於定義一個由直線/曲線組合而成的路徑, 並且可以在自定義視圖中渲染該路徑。 

 

UIBezierPath方法和屬性

//創建並且返回一個新的 UIBezierPath 對象
+ (instancetype) bezierPath;
/**
  * 該方法將會創建一個閉合路徑, 起始點是 rect 參數的的 origin, 並且按照順時針方向添加直線, 最終形成矩形
  * @param rect:   矩形路徑的 Frame
  */
+ (instancetype)bezierPathWithRect:(CGRect)rect;
/**
  * 該方法將會創建一個閉合路徑,  該方法會通過順時針的繪制貝塞爾曲線, 繪制出一個近似橢圓的形狀. 如果 rect 參數指定了一個矩形, 那么該 UIBezierPath 對象將會描述一個圓形.
  * @param rect:   矩形路徑的 Frame
  */
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
/**
  * 該方法將會創建一個閉合路徑,  該方法會順時針方向連續繪制直線和曲線.  當 rect 為正方形時且 cornerRadius 等於邊長一半時, 則該方法會描述一個圓形路徑.
  * @param rect:   矩形路徑的 Frame
  * @param cornerRadius:   矩形的圓角半徑
  */
+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect 
                              cornerRadius:(CGFloat)cornerRadius;
/**
  * 該方法將會創建一個閉合路徑,  該方法會順時針方向連續繪制直線和曲線.  
  * @param rect:   矩形路徑的 Frame
  * @param corners:   UIRectCorner 枚舉類型, 指定矩形的哪個角變為圓角
  * @param cornerRadii:   矩形的圓角半徑
  */
+ (instancetype) bezierPathWithRoundedRect:(CGRect)rect 
                         byRoundingCorners:(UIRectCorner)corners
                               cornerRadii:(CGSize)cornerRadii;
/**
  * 該方法會創建出一個開放路徑, 創建出來的圓弧是圓的一部分. 在默認的坐標系統中, 開始角度 和 結束角度 都是基於單位圓的(看下面這張圖). 調用這個方法之后, currentPoint 將會設置為圓弧的結束點.
  * 舉例來說: 指定其實角度為0, 指定結束角度為π, 設置 clockwise 屬性為 YES, 將會繪制出圓的下半部分.
  * 然而當我們不修改起始角度 和 結束角度, 我們僅僅將 clockwise 角度設置為 NO, 則會繪制出來一個圓的上半部分.
  * @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 對象
+ (instancetype) bezierPathWithCGPath:(CGPathRef)CGPath;
/**
  * 通過該方法反轉一條路徑, 並不會修改該路徑的樣子. 它僅僅是修改了繪制的方向
  * @return: 返回一個新的 UIBezierPath 對象, 形狀和原來路徑的形狀一樣,
  *          但是繪制的方向相反.
  */
- (UIBezierPath *) bezierPathByReversingPath;
/**
  * 如果當前有正在繪制的子路徑, 該方法則會隱式的結束當前路徑, 
  * 並將 currentPoint 設置為指定點. 當上一條子路徑被終止, 該方法
  * 實際上並不會去閉合上一條子路徑. 所以上一條自路徑的起始點 和
  * 結束點並沒有被鏈接.
  * 對於大多數構造路徑相關的方法而言, 在你繪制直線或曲線之前, 需要先調用這個方法.
  * @param point:   當前坐標系統中的某一點
  */
- (void)moveToPoint:(CGPoint)point;
/**
  * 該方法將會從 currentPoint 到 指定點 鏈接一條直線. 
  * Note: 在追加完這條直線后, 該方法將會更新 currentPoint 為 指定點
  *       調用該方法之前, 你必須先設置 currentPoint. 如果當前繪制路徑
  *       為空, 並且未設置 currentPoint, 那么調用該方法將不會產生任何
  *       效果.
  * @param point:   繪制直線的終點坐標, 當前坐標系統中的某一點
  */
- (void)addLineToPoint:(CGPoint)point;
/**
  * 該方法將會從 currentPoint 添加一條指定的圓弧.
  * 該方法的介紹和構造方法中的一樣. 請前往上文查看
  * @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);
/**
  * 該方法將會從 currentPoint 到 指定的 endPoint 追加一條二次貝塞爾曲線.
  * currentPoint、endPoint、controlPoint 三者的關系最終定義了二次貝塞爾曲線的形狀.
  * 二次貝塞爾曲線的彎曲由一個控制點來控制. 如下圖所示
  * Note: 調用該方法前, 你必須先設置 currentPoint, 如果路徑為空, 
  *       並且尚未設置 currentPoint, 調用該方法則不會產生任何效果. 
  *       當添加完貝塞爾曲線后, 該方法將會自動更新 currentPoint 為
  *       指定的結束點
  * @param endPoint: 終點
  * @param controlPoint: 控制點
  */
- (void)addQuadCurveToPoint:(CGPoint)endPoint 
               controlPoint:(CGPoint)controlPoint;
/**
  * 該方法將會從 currentPoint 到 指定的 endPoint 追加一條三次貝塞爾曲線.
  * 三次貝塞爾曲線的彎曲由兩個控制點來控制. 如下圖所示
  * Note: 調用該方法前, 你必須先設置 currentPoint, 如果路徑為空, 
  *       並且尚未設置 currentPoint, 調用該方法則不會產生任何效果. 
  *       當添加完貝塞爾曲線后, 該方法將會自動更新 currentPoint 為
  *       指定的結束點
  * @param endPoint: 終點
  * @param controlPoint1: 控制點1
  * @param controlPoint2: 控制點2
  */
- (void)addCurveToPoint:(CGPoint)endPoint 
          controlPoint1:(CGPoint)controlPoint1 
          controlPoint2:(CGPoint)controlPoint2;
/**
  * 該方法將會從 currentPoint 到子路經的起點 繪制一條直線, 
  * 以此來關閉當前的自路徑. 緊接着該方法將會更新 currentPoint
  * 為 剛添加的這條直線的終點, 也就是當前子路經的起點.
  */
- (void)closePath;
//刪除 UIBezierPath 對象中的所有點, 效果也就等同於刪除了所有子路經
- (void)removeAllPoints;
/**
  * 該方法將會在當前 UIBezierPath 對象的路徑中追加
  * 指定的 UIBezierPath 對象中的內容. 
  */
- (void)appendPath:(UIBezierPath *)bezierPath;
/**
  * 獲取這個屬性, 你將會獲得一個不可變的 CGPathRef 對象,
  * 他可以傳入 CoreGraphics 提供的函數中
  * 你可以是用 CoreGraphics 框架提供的方法創建一個路徑, 
  * 並給這個屬性賦值, 當時設置了一個新的路徑后, 
  * 這個將會對你給出的路徑對象進行 Copy 操作
  */
@property(nonatomic) CGPathRef CGPath;
/**
  * 該屬性的值, 將會是下一條繪制的直線或曲線的起始點.
  * 如果當前路徑為空, 那么該屬性的值將會是 CGPointZero
  */
@property(nonatomic, readonly) CGPoint currentPoint;
/**
  * 線寬屬性定義了 `UIBezierPath` 對象中繪制的曲線規格. 默認為: 1.0
  */
@property(nonatomic) CGFloat lineWidth;
//曲線終點樣式
/**
  * 該屬性應用於曲線的終點和起點. 該屬性在一個閉合子路經中是無效果的. 默認為: kCGLineCapButt
  */
@property(nonatomic) CGLineCap lineCapStyle;


// CGPath.h
/* Line cap styles. */
typedef CF_ENUM(int32_t, CGLineCap) {
    kCGLineCapButt,
    kCGLineCapRound,
    kCGLineCapSquare
};
//曲線連接點樣式
/**
  * 默認為: kCGLineJoinMiter.
  */
@property(nonatomic) CGLineJoin lineJoinStyle;


// CGPath.h
/* Line join styles. */
typedef CF_ENUM(int32_t, CGLineJoin) {
    kCGLineJoinMiter,
    kCGLineJoinRound,
    kCGLineJoinBevel
};
//內角和外角距離
/**
  * 兩條線交匯處內角和外角之間的最大距離, 只有當連接點樣式為 kCGLineJoinMiter
  * 時才會生效,最大限制為10
  * 我們都知道, 兩條直線相交時, 夾角越小, 斜接長度就越大.
  * 該屬性就是用來控制最大斜接長度的.
  * 當我們設置了該屬性, 如果斜接長度超過我們設置的范圍, 
  * 則連接處將會以 kCGLineJoinBevel 連接類型進行顯示.
  */
@property(nonatomic) CGFloat miterLimit;
//渲染精度
/**
  * 該屬性用來確定渲染曲線路徑的精確度.
  * 該屬性的值用來測量真實曲線的點和渲染曲線的點的最大允許距離.
  * 值越小, 渲染精度越高, 會產生相對更平滑的曲線, 但是需要花費更
  * 多的計算時間. 值越大導致則會降低渲染精度, 這會使得渲染的更迅
  * 速. flatness 的默認值為 0.6.
  * Note: 大多數情況下, 我們都不需要修改這個屬性的值. 然而當我們
  *       希望以最小的消耗去繪制一個臨時的曲線時, 我們也許會臨時增
  *       大這個值, 來獲得更快的渲染速度.
  */

@property(nonatomic) CGFloat flatness;
/**
  * 設置為 YES, 則路徑將會使用 基偶規則 (even-odd) 進行填充.
  * 設置為 NO,  則路徑將會使用 非零規則 (non-zero) 規則進行填充.
  */
@property(nonatomic) BOOL usesEvenOddFillRule;
//虛線
/**
  * @param pattern: 該屬性是一個 C 語言的數組, 其中每一個元素都是 CGFloat
  *                 數組中的元素代表着線段每一部分的長度, 第一個元素代表線段的第一條線,
  *                 第二個元素代表線段中的第一個間隙. 這個數組中的值是輪流的. 來解釋一下
  *                 什么叫輪流的. 
  *                 舉個例子: 聲明一個數組 CGFloat dash[] = @{3.0, 1.0}; 
  *                 這意味着繪制的虛線的第一部分長度為3.0, 第一個間隙長度為1.0, 虛線的
  *                 第二部分長度為3.0, 第二個間隙長度為1.0. 以此類推.

  * @param count: 這個參數是 pattern 數組的個數
  * @param phase: 這個參數代表着, 虛線從哪里開始繪制.
  *                 舉個例子: 這是 phase 為 6. pattern[] = @{5, 2, 3, 2}; 那么虛線將會
  *                 第一個間隙的中間部分開始繪制, 如果不是很明白就請繼續往下看,
  *                 下文實戰部分會對虛線進行講解.
  */
- (void)setLineDash:(const CGFloat *)pattern
              count:(NSInteger)count
              phase:(CGFloat)phase;
//重新獲取虛線的模式
/**
  * 該方法可以重新獲取之前設置過的虛線樣式.
  *  Note:  pattern 這個參數的容量必須大於該方法返回數組的容量.
  *         如果無法確定數組的容量, 那么可以調用兩次該方法, 第一次
  *         調用該方法的時候, 傳入 count 參數, 然后在用 count 參數
  *         來申請 pattern 數組的內存空間. 然后再第二次正常的調用該方法
  */
- (void)getLineDash:(CGFloat *)pattern 
              count:(NSInteger *)count
              phase:(CGFloat *)phase;
//填充路徑
/**
  * 該方法當前的填充顏色 和 繪圖屬性對路徑的封閉區域進行填充.
  * 如果當前路徑是一條開放路徑, 該方法將會隱式的將路徑進行關閉后進行填充
  * 該方法在進行填充操作之前, 會自動保存當前繪圖的狀態, 所以我們不需要
  * 自己手動的去保存繪圖狀態了. 
  */
- (void)fill;
//使用混合模式進行填充
/**
  * 該方法當前的填充顏色 和 繪圖屬性 (外加指定的混合模式 和 透明度) 
  * 對路徑的封閉區域進行填充. 如果當前路徑是一條開放路徑, 該方法將
  * 會隱式的將路徑進行關閉后進行填充
  * 該方法在進行填充操作之前, 會自動保存當前繪圖的狀態, 所以我們不需要
  * 自己手動的去保存繪圖狀態了. 
  *
  * @param blendMode: 混合模式決定了如何和已經存在的被渲染過的內容進行合成
  * @param alpha: 填充路徑時的透明度
  */
- (void)fillWithBlendMode:(CGBlendMode)blendMode 
                    alpha:(CGFloat)alpha;
//繪制路徑
- (void)stroke;
/**
  * @param blendMode: 混合模式決定了如何和已經存在的被渲染過的內容進行合成
  * @param alpha: 填充路徑時的透明度
  */
- (void)strokeWithBlendMode:(CGBlendMode)blendMode
                      alpha:(CGFloat)alpha;
//剪切路徑
/**
  *  該方法將會修改當前繪圖上下文的可視區域.
  *  當調用這個方法之后, 會導致接下來所有的渲染
  *  操作, 只會在剪切下來的區域內進行, 區域外的
  *  內容將不會被渲染.
  *  如果你希望執行接下來的繪圖時, 刪除剪切區域,
  *  那么你必須在調用該方法前, 先使用 CGContextSaveGState 方法
  *  保存當前的繪圖狀態, 當你不再需要這個剪切區域
  *  的時候, 你只需要使用 CGContextRestoreGState 方法
  *  來恢復之前保存的繪圖狀態就可以了.
  * @param blendMode: 混合模式決定了如何和
  *                   已經存在的被渲染過的內容進行合成
  * @param alpha: 填充路徑時的透明度
  */
- (void)addClip;
//是否包含某個點
/**
  *  該方法返回一個布爾值, 當曲線的覆蓋區域包含
  * 指定的點(內部點), 則返回 YES, 否則返回 NO. 
  * Note: 如果當前的路徑是一個開放的路徑, 那么
  *       就算指定點在路徑覆蓋范圍內, 該方法仍然會
  *       返回 NO, 所以如果你想判斷一個點是否在一個
  *       開放路徑的范圍內時, 你需要先Copy一份路徑,
  *       並調用 -(void)closePath; 將路徑封閉, 然后
  *       再調用此方法來判斷指定點是否是內部點.
  * @param point: 指定點.
  */
- (BOOL) containsPoint:(CGPoint)point;
//路徑是否為空
/**
  * 檢測當前路徑是否繪制過直線或曲線.
  * Note: 記住, 就算你僅僅調用了 moveToPoint 方法
  *       那么當前路徑也被看做不為空.
  */
@property (readonly, getter=isEmpty) BOOL empty;
//路徑覆蓋的矩形區域
/**
  * 該屬性描述的是一個能夠完全包含路徑中所有點
  *  的一個最小的矩形區域. 該區域包含二次貝塞爾
  *  曲線和三次貝塞爾曲線的控制點.
  */
@property (nonatomic, readonly) CGRect bounds;
/**
  * 該方法將會直接對路徑中的所有點進行指定的放射
  * 變換操作. 
  */
- (void)applyTransform:(CGAffineTransform)transform;

 

UIBezierPath使用方式

*使用CAShapeLayer直接添加在視圖圖層上

//用CAShapeLayer渲染一個簡單的火柴人
-(void)createMatchPeople{
    //使用UIBezierPath創建圖層路徑
    UIBezierPath *path=[[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(175, 100)];
    [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
    [path moveToPoint:CGPointMake(150, 125)];
    [path addLineToPoint:CGPointMake(150, 175)];
    [path addLineToPoint:CGPointMake(125, 225)];
    [path moveToPoint:CGPointMake(150, 175)];
    [path addLineToPoint:CGPointMake(175, 225)];
    [path moveToPoint:CGPointMake(100, 150)];
    [path addLineToPoint:CGPointMake(200, 150)];
    
    
    //創建CAShapeLayer
    CAShapeLayer *shapeLayer=[CAShapeLayer layer];
    shapeLayer.strokeColor=[UIColor redColor].CGColor;
    shapeLayer.fillColor=[UIColor clearColor].CGColor;
    shapeLayer.lineWidth=5;
    shapeLayer.lineJoin=kCALineJoinRound;
    shapeLayer.lineCap=kCALineCapRound;
    shapeLayer.path=path.CGPath;
    [self.view.layer addSublayer:shapeLayer];
}

 

*自定義UIView中繪制和渲染

//自定義TestBezierPathView.m

 

//
//  TestBezierPathView.m
//  UIBezierPathLearn
//
//  Created by Vie on 2017/8/15.
//  Copyright © 2017年 Vie. All rights reserved.
//

#import "TestBezierPathView.h"

@implementation TestBezierPathView


- (void)drawRect:(CGRect)rect {

    [self createIndicatorArrow];

}

//指標箭頭
-(void)createIndicatorArrow{
    UIBezierPath* p = [UIBezierPath bezierPath];
    // 繪制一個黑色的垂直黑色線,作為箭頭的桿子
    [p moveToPoint:CGPointMake(100,100)];
    [p addLineToPoint:CGPointMake(100, 19)];
    [p setLineWidth:20];
    [p stroke];
    // 繪制一個紅色三角形箭頭
    [[UIColor redColor] set];
    [p removeAllPoints];
    [p moveToPoint:CGPointMake(80,25)];
    [p addLineToPoint:CGPointMake(100, 0)];
    [p addLineToPoint:CGPointMake(120, 25)];
    [p fill];
    // 從箭頭桿子上裁掉一個三角形
    [p removeAllPoints];
    [p moveToPoint:CGPointMake(90,101)];
    [p addLineToPoint:CGPointMake(100, 90)];
    [p addLineToPoint:CGPointMake(110, 101)];
    // 從箭頭桿子上裁掉一個三角形,使用清除混合模式,背景為無色或透明的話裁剪區域就是透明,否則為黑色
    [p fillWithBlendMode:kCGBlendModeClear alpha:1.0];
}
//畫圓角矩形
-(void)createRoundedRectangle{
    //四個角都是圓角
    UIBezierPath *path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 70, 70) cornerRadius:10];;
    //設置畫筆顏色
    UIColor *yellowColor=[UIColor yellowColor];
    [yellowColor set];
    [path stroke];
    
    //指定方向上的角為圓角
    UIBezierPath *path2=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 140, 140) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
    //設置畫筆顏色
    UIColor *cyanColor=[UIColor cyanColor];
    [cyanColor set];
    [path2 stroke];
}

//渲染BezierPath對象的內容
-(void)createDrawingBezierPath{
    //創造一個橢圓形的輪廓
    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)];
    //設置渲染顏色
    [[UIColor yellowColor] setStroke];
    [[UIColor redColor] setFill];
    //調整graphic context相對於調整path對象的points是首選的方法,因為我們可以很容易的保存和撤銷先前的graphics state。
    CGContextRef ref=UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ref, 10, 50);
    path.lineWidth=5;
    [path fill];
    [path stroke];
}

//使用Core Graphics函數和UIBezierPath函數混合方法
-(void)createPathDataAndBezierPath{
    UIColor *cyanColor=[UIColor cyanColor];
    [cyanColor set];//設置線條顏色
    //應該生成一個副本,然后修改此副本,然后賦值此副本給CGPath屬性
    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];
    CGPathRef cgPath=path.CGPath;
    CGMutablePathRef mutablePath=CGPathCreateMutableCopy(cgPath);
    CGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));
    path.CGPath=mutablePath;
    [path stroke];
    CGPathRelease(mutablePath);
    
}
//使用CoreGraphics函數去修改path
-(void)createPathData{
    UIColor *cyanColor=[UIColor cyanColor];
    [cyanColor set];//設置線條顏色
    //創建路徑數據
    CGMutablePathRef cgPath=CGPathCreateMutable();
    //矩形內切圓或橢圓
    CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 0, 300, 300));
    CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 50, 200, 150));
    //創建貝塞爾曲線
    UIBezierPath *path=[UIBezierPath bezierPath];
    path.CGPath=cgPath;
    [path stroke];
    CGPathRelease(cgPath);
}

//使用三次貝塞爾曲線
-(void)createThreeBezierCurve{
    UIColor *magentaColor=[UIColor magentaColor];
    [magentaColor set];
    //繪制三次貝塞爾曲線;曲線段在當前點開始,在指定的點結束。曲線的形狀有開始點,結束點,兩個控制點的切線定義。
    UIBezierPath *path=[UIBezierPath bezierPath];
    path.lineWidth=5.0;
    [path moveToPoint:CGPointMake(0, 150)];
    [path addCurveToPoint:CGPointMake(180, 0) controlPoint1:CGPointMake(60, 0) controlPoint2:CGPointMake(120, 150)];
    [path stroke];
}

//使用二次貝塞爾曲線
-(void)createSecondaryBezierCurve{
    UIColor *purpleColor=[UIColor purpleColor];
    [purpleColor set];
    //繪制二次貝塞爾曲線;曲線段在當前點開始,在指定的點結束。曲線的形狀有開始點,結束點,一個控制點的切線定義。
    UIBezierPath *path=[UIBezierPath bezierPath];
    path.lineWidth=5.0;
    [path moveToPoint:CGPointMake(20, 300)];
    [path addQuadCurveToPoint:CGPointMake(120, 300) controlPoint:CGPointMake(70, 0)];
    [path stroke];
}

//創建一段弧線
-(void)createArc{
    UIColor *brownColor=[UIColor brownColor];
    [brownColor set];
    //使用UIBezierPath創建一段弧線;圓弧中心,半徑,開始角度,結束角度,是否順時針方向
    UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:80 startAngle:0 endAngle:M_PI_2 clockwise:NO];
    path.lineWidth=5.0f;
    [path stroke];
}
//創建圓形或橢圓
-(void)createCircularOrEllipse{
    UIColor *cyanColor=[UIColor cyanColor];
    [cyanColor set];//設置線條顏色
    //創建圓形或橢圓,根據傳入的rect矩形參數繪制一個內切曲線
    UIBezierPath *path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 100, 100)];
    path.lineWidth=5.0;
    [path stroke];
}
//創建矩形
-(void)createRectangular{
    UIColor *orangeColor=[UIColor cyanColor];
    [orangeColor set];//設置線條顏色
    //創建矩形
    UIBezierPath *path=[UIBezierPath bezierPathWithRect:CGRectMake(20, 20,100 , 100)];
    path.lineWidth=5.0;
    [path stroke];
}

//創建五邊形
-(void)createPentagon{
    UIColor *redColor=[UIColor redColor];
    [redColor set];//設置線條顏色
    UIBezierPath *path=[UIBezierPath bezierPath];
    path.lineWidth=5.0;
    path.lineCapStyle=kCGLineCapRound;//線條拐角
    path.lineJoinStyle=kCGLineCapRound;//終點處理
    [path moveToPoint:CGPointMake(100.0, 0.0)];
    
    //畫線
    [path addLineToPoint:CGPointMake(200.0, 40.0)];
    [path addLineToPoint:CGPointMake(160.0, 140.0)];
    [path addLineToPoint:CGPointMake(40.0, 140.0)];
    [path addLineToPoint:CGPointMake(0.0, 40.0)];
    [path closePath];//第五條線通過調用closePath方法得到的
    [path stroke];//使用當前的繪圖屬性在接收方的路徑上畫一條線。
//    [path fill];//用當前的繪圖特性繪制受接收器路徑所包圍的區域。
}
-(void)test{
    // 1. 隨便畫一個路徑出來.
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint: CGPointMake(10, 10)];
    [path addLineToPoint: CGPointMake(80, 40)];
    [path addLineToPoint: CGPointMake( 40,  80)];
    [path addLineToPoint: CGPointMake(40, 40)];
    path.lineWidth = 3;
    
    // 2. 為這條路徑制作一個反轉路徑
    UIBezierPath *reversingPath = [path bezierPathByReversingPath];
    reversingPath.lineWidth = 3;
    
    // 3. 為了避免兩條路徑混淆在一起, 我們為第一條路徑做一個位移
    CGAffineTransform transform = CGAffineTransformMakeTranslation(200, 0);
    [path applyTransform: transform];
    
    // 4. 兩條路徑分別添加一條直接到 self.center
    [path addLineToPoint: CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5)];
    [reversingPath addLineToPoint: CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5)];
    
    // 5. 設置顏色, 並繪制路徑
    [[UIColor redColor] set];
    [path stroke];
    
    [[UIColor greenColor] set];
    [reversingPath stroke];
}
- (void) typeDashLine {
    
    // 1. 先創建三條路徑, 有對比更有助於理解
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint: CGPointMake(80, 40)];
    [path addLineToPoint: CGPointMake(self.frame.size.width - 40, 40)];
    path.lineWidth = 2;
    
    
    UIBezierPath *path1 = [UIBezierPath bezierPath];
    [path1 moveToPoint: CGPointMake(80, 80)];
    [path1 addLineToPoint: CGPointMake(self.frame.size.width - 40, 80)];
    path1.lineWidth = 2;
    
    
    UIBezierPath *path2 = [UIBezierPath bezierPath];
    [path2 moveToPoint: CGPointMake(80, 120)];
    [path2 addLineToPoint: CGPointMake(self.frame.size.width - 40, 120)];
    path2.lineWidth = 2;
    
    // 2.  這部分是配置三條路徑虛線的規格, 重點主要是這部分.
    CGFloat dashLineConfig[] = {8.0, 4.0};
    [path setLineDash: dashLineConfig
                count: 2
                phase: 0];
    
    
    CGFloat dashLineConfig1[] = {8.0, 4.0, 16.0, 8.0};
    [path1 setLineDash: dashLineConfig1
                 count: 4
                 phase: 0];
    
    
    CGFloat dashLineConfig2[] = {8.0, 4.0, 16.0, 8.0};
    [path2 setLineDash: dashLineConfig2
                 count: 4
                 phase: 12];
    
    // 3. 繪制
    [[UIColor orangeColor] set];
    [path stroke];
    [path1 stroke];
    [path2 stroke];
}

@end

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM