UIBezierPath的使用

最近研究了下UIBezierPath,雖然他的構造方法不是特別多,可是感受仍是特別實用的,就是用起來感受很方便,其主要做用仍是用於爲視圖的Layer層添加路徑,至關於根據咱們建立的path來對目標視圖進行切割.好比說我要把一個視圖的形狀裁剪一下,或者我想自定義一個幾何圖形什麼的,用UIBezierPath來實現都是很方便的.惟一不方便的地方就是若是要在一個view上只使用UIBezierPath來進行繪製幾何圖形的話,那麼必需要在- (void)drawRect:(CGRect)rect方法裏繪製或者調用,這樣一來就給咱們帶來了些許的限制,因此,在平常的開發中,若是要建立自定義的幾何圖形的話,常常仍是使用CAShapeLayer和UIBezierPath共同來建立.各位看官能夠看下個人這篇博客:CAShapeLayer的使用,但願能給各位大人帶來少量幫助.git

不過,今天咱們就事論事,只說UIBezierPath的使用,下面是我寫的一個Demo,能夠先看下效果github

這個Demo裏包括了UIBezierPath使用頻率最高的幾種幾何圖形以及建立的方法,其實UIBezierPath的使用很簡單,只不過有些細節須要注意下,下面就先看一下UIBezierPath提供的構造方法(由於對UIBezierPath對象的設置不少地方都是雷同的,因此第一個構造方法我會詳細講解使用方法,後面的幾個就不詳細講解了,該Demo我已經上傳到github,各位看官能夠去github下載完整的工程代碼,包括了使用實例,連接我會在後面貼出來): 
- +(instancetype)bezierPath; 
該方法直接返回一個UIBezierPath對象,不須要傳遞任何參數,咱們能夠直接對建立出來的對象操做,使用方法以下:sql

//繪製一個三角形 -(void)drawtriangle{ //繪製一條完整路徑 首先建立路徑對象,接着按繪製順序添加關鍵點,最後調用[path closePath]方法閉合路徑 UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(40, self.frame.size.height - 40)]; [path addLineToPoint:CGPointMake(k_ScreenWidth - 40, self.frame.size.height - 40)]; [path addLineToPoint:CGPointMake(k_ScreenWidth/2, 40)]; [path closePath]; /*設置填充顏色 建立一個顏色對象以後,須要調用顏色的set方法設置上下文環境,接着調用路徑的fill方法使用上下文環境中的顏色來填充 Tip: 這個fill方法頗有意思 若是第一次設置上下文環境爲紅色,那麼調用fill的則會爲該路徑內填充紅色 可是第二次設置上下文環境爲綠色時,調用fill方法並非說將路徑內的紅色替換掉,而是在紅色的上方填充一次綠色 我會在博客裏驗證,讀者也可自行驗證 */ UIColor *redColor = [UIColor redColor]; [redColor set]; [path fill]; //設置線條屬性 各類格式我會貼出來給你們看,方便對比 path.lineCapStyle = kCGLineJoinRound; //線段端點格式 path.lineJoinStyle = kCGLineJoinRound; //線段接頭格式 path.lineWidth = 8; //設置路徑顏色 原理和設置填充顏色同樣,這不過是調用[path stroke]方法來設置路徑額顏色 設置線寬爲8 UIColor *blackColor = [UIColor blackColor]; [blackColor set]; [path stroke]; }

 

  • 上文提到了lineCapStyle和lineJoinStyle,這兩個屬性分別對應的是線條端點的風格和線條接頭處的風格,有如下三個枚舉值:
typedef CF_ENUM(int32_t, CGLineJoin) { kCGLineJoinMiter, kCGLineJoinRound, kCGLineJoinBevel };

對應的風格以下所示:markdown

端點處的風格:(lineCapStyle)
kCGLineJoinMiter,
kCGLineJoinBevel  這兩個風格是同樣的,都是直角風格以下所示:

kCGLineJoinRound,圓角風格,以下所示:

接頭處的風格:(lineJoinStyle)ui

kCGLineJoinMiter  斜接

kCGLineJoinRound  圓角

kCGLineJoinBevel  斜角

 
- +(instancetype)bezierPathWithRect:(CGRect)rect; 
該方法會根據傳進去的CGRect結構體來建立一個矩形spa

  • +(instancetype)bezierPathWithOvalInRect:(CGRect)rect; 
    該方法會根據傳進去的結構體(矩形)建立一個內切圓,若是該矩形是正方形的話,那麼切出來的是一個圓形,若是是長方形的話,切出來的則是一個橢圓
  • +(instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
    該方法會根據傳進去的矩形和圓角角度建立一個四個角都是圓角的矩形
  • +(instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii; 
    參數解析: 
    rect: 基礎矩形 
    corners: 選擇矩形中須要添加圓角的位置,該值有四個枚舉值,以下所示: 
    UIRectCornerTopLeft 左上方添加 
    UIRectCornerTopRight 右上方添加 
    UIRectCornerBottomLeft 左下方添加 
    UIRectCornerBottomRight 右下方添加 
    UIRectCornerAllCorners 所有添加 
    傳值的時候,能夠傳進去單獨的值,如:UIRectCornerTopLeft(在左上角添加圓角),能夠傳進去多個值,中間使用’|’隔開,如:UIRectCornerTopLeft|UIRectCornerTopRight(給左上角和右上角添加圓角) 
    ornerRadii:這個參數的意思是,傳進去一個矩形A的寬高,以須要添加的角的頂點爲矩形A的左上角,在該矩形內作內切圓,爲矩形添加圓角.
  • +(instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; 
    該方法是用來繪製圓形的 
    參數解析: 
    center 圓心位置 
    radius 半徑 
    startAngle 開始角度,默認從3點鐘開始 
    endAngle 結束角度 
    clockwise 是否順時針方向繪製.net

  • +(instancetype)bezierPathWithCGPath:(CGPathRef)CGPath; 
    該方法和第一個方法類型相似,只不過該方法傳進去的是一個CGPath的路徑.code

  • 關於fill的討論 
    上文中提到, 
    Tip: 這個fill方法頗有意思 
    若是第一次設置上下文環境爲紅色,那麼調用fill的則會爲該路徑內填充紅色 
    可是第二次設置上下文環境爲綠色時,調用fill方法並非說將路徑內的紅色替換掉,而是在紅色的上方填充一次綠色 
    如今咱們就來驗證一下這個說法,首先,咱們繪製一個圓形,代碼以下,填充顏色爲紅色,邊框顏色爲黑色,線寬30:對象

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 80, k_ScreenWidth - 80, k_ScreenWidth - 80)]; //設置填充顏色 UIColor *redColor = [UIColor redColor]; [redColor set]; [path fill]; //設置路徑格式 path.lineWidth = 30.0; path.lineCapStyle = kCGLineJoinRound; path.lineJoinStyle = kCGLineJoinRound; //設置路徑顏色 UIColor *blackColor = [UIColor blackColor]; [blackColor set]; [path stroke];

 

效果以下:blog

而後咱們在末尾再次填充顏色,執行代碼以下:

UIColor *greenColor = [UIColor greenColor];
    [greenColor set]; [path fill];
  • 效果以下所示:

咱們很清楚的能夠看出來,邊框的寬度減小了一半,緣由就是當咱們再次調用fill方法的時候,該方法是在原有圖層上又添加了一層圖像.因爲路徑的繪製原則是向內外擴展,咱們設置的路徑寬度是30,那麼它就會向內擴展15向外擴展15.當咱們再次繪製圖層的時候,因爲是在原來的基礎上填充的,那麼就會將向內擴展的15個單位的路徑覆蓋上,就致使了咱們看到路徑寬度比原來減小了一半的效果.

 //繪製一個三角形 該方法會詳細講述各個參數的意思及使用方法,後面的方法僅僅展現使用方法 -(void)drawtriangle{ //繪製一條完整路徑 首先建立路徑對象,接着按繪製順序添加關鍵點,最後調用[path closePath]方法閉合路徑 UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(40, self.frame.size.height - 40)]; [path addLineToPoint:CGPointMake(k_ScreenWidth - 40, self.frame.size.height - 40)]; [path addLineToPoint:CGPointMake(k_ScreenWidth/2, 40)]; [path closePath]; /*設置填充顏色 建立一個顏色對象以後,須要調用顏色的set方法設置上下文環境,接着調用路徑的fill方法使用上下文環境中的顏色來填充 Tip: 這個fill方法頗有意思 若是第一次設置上下文環境爲紅色,那麼調用fill的則會爲該路徑內填充紅色 可是第二次設置上下文環境爲綠色時,調用fill方法並非說將路徑內的紅色替換掉,而是在紅色的上方填充一次綠色 我會在博客裏驗證,讀者也可自行驗證 */ UIColor *redColor = [UIColor redColor]; [redColor set]; [path fill]; //設置線條屬性 path.lineCapStyle = kCGLineJoinRound; //線段端點格式 path.lineJoinStyle = kCGLineJoinRound; //線段接頭格式 path.lineWidth = 8; //設置路徑顏色 原理和設置填充顏色同樣,這不過是調用[path stroke]方法來設置路徑額顏色 設置線寬爲8 UIColor *blackColor = [UIColor blackColor]; [blackColor set]; [path stroke]; } #pragma mark:因爲設置填充顏色、線條顏色、線條寬度代碼重複冗餘,因此將其寫到一個方法裏,統一設置爲填充顏色爲紅色,線條顏色爲黑色,線條寬度爲8 //繪製一個矩形 -(void)drawRectangle{ UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80)]; [self setPath:path]; } //繪製一個實心圓形 -(void)drawFillCircle{ /* 該方法是使用一個矩形爲基準繪製其內切圓 當該矩形是正方形時,繪製出的爲圓形 當該矩形爲長方形的時候,繪製出來的是橢圓 */ UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 80, k_ScreenWidth - 80, k_ScreenWidth - 80)]; [self setPath:path]; } //繪製一個空心圓形 主要爲了展現使用不一樣的工廠方法來建立圓形 -(void)drawEmptyCircle{ UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(k_ScreenWidth/2, k_CurrentHeight - 300) radius:(k_ScreenWidth - 40)/2 startAngle:0 endAngle:k_DegreesToRadians(360) clockwise:YES]; //設置填充顏色 UIColor *redColor = [UIColor clearColor]; [redColor set]; [path fill]; //設置路徑格式 path.lineWidth = 8; path.lineCapStyle = kCGLineJoinRound; path.lineJoinStyle = kCGLineJoinRound; //設置路徑顏色 UIColor *blackColor = [UIColor blackColor]; [blackColor set]; [path stroke]; } //繪製一個四個角都是圓角額矩形 -(void)drawCornerRectangle{ UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80) cornerRadius:20]; [self setPath:path]; } //繪製一個可選角度的矩形 -(void)drawRectWithLeftAndRightCorner{ /* 參數解析: bezierPathWithRoundedRect 繪製矩形的大小 byRoundingCorners 有哪幾個角須要繪製 cornerRadii 圓角角度,使用角的頂點做爲圓心來切圓角 */ UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40,40 ,k_CurrentWidth - 80 , k_CurrentHeight - 80) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake((k_CurrentWidth - 80)/2, (k_CurrentWidth - 80)/2)]; [self setPath:path]; } - (void)drawSecondBezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; //設置一個起始點 [path moveToPoint:CGPointMake(20, self.frame.size.height - 100)]; // 添加二次曲線 [path addQuadCurveToPoint:CGPointMake(self.frame.size.width - 20, self.frame.size.height - 100) controlPoint:CGPointMake(self.frame.size.width / 2, 0)]; path.lineCapStyle = kCGLineJoinBevel; path.lineJoinStyle = kCGLineJoinRound; path.lineWidth = 8.0; UIColor *strokeColor = [UIColor blackColor]; [strokeColor set]; [path stroke]; } - (void)drawThirdBezierPath { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(20, 200)]; [path addCurveToPoint:CGPointMake(300, 200) controlPoint1:CGPointMake(160, 50) controlPoint2:CGPointMake(160, 300)]; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; path.lineWidth = 5.0; UIColor *strokeColor = [UIColor blackColor]; [strokeColor set]; [path stroke]; } -(void)setPath:(UIBezierPath*)path{ //設置填充顏色 UIColor *redColor = [UIColor redColor]; [redColor set]; [path fill]; //設置路徑格式 path.lineWidth = 8.0; path.lineCapStyle = kCGLineJoinRound; path.lineJoinStyle = kCGLineJoinRound; //設置路徑顏色 UIColor *blackColor = [UIColor blackColor]; [blackColor set]; [path stroke]; }
相關文章
相關標籤/搜索