IOS圖形繪制路徑 CGPATH & CGCONTEXT相關(guān)聯(lián)的CGPath & UIBezierPath

獨(dú)立CGPath總結(jié)

CGPathCreateMutable //創(chuàng)建一個(gè)可變圖形的路徑 需要自己釋放
CGPathCreateWithEllipseInRect //創(chuàng)建一個(gè)橢圓形的不可改變的路徑
CGPathCreateWithRect //創(chuàng)建一個(gè)不變的矩形路徑
CGPathCreateCopy //創(chuàng)建一個(gè)不可變的可以拷貝的路徑
CGPathCreateCopyByDashingPath //創(chuàng)建一個(gè)虛線(xiàn)路徑可以復(fù)制的
CGPathCreateCopyByStrokingPath //創(chuàng)建一個(gè)畫(huà)的路徑
CGPathCreateMutableCopy //創(chuàng)建一個(gè)現(xiàn)有的圖形路徑的副本
 //由一個(gè)轉(zhuǎn)換矩陣變換一個(gè)圖形路徑創(chuàng)建一個(gè)不可變的副本
CGPathCreateCopyByTransformingPath
//創(chuàng)建一個(gè)由一個(gè)轉(zhuǎn)換矩陣變換一個(gè)圖形路徑的可變副本
CGPathCreateMutableCopyByTransformingPath


CGPathRelease //遞減保留的圖形路徑計(jì)數(shù)
CGPathRetain //增加保留的圖形路徑計(jì)數(shù)

CGPathAddArc 一個(gè)//弧形追加一個(gè)可變圖形的路徑, 可能由直線(xiàn)段之前
CGPathAddEllipseInRect //添加一個(gè)適合的橢圓在矩形的內(nèi)部
CGPathEqualToPath //兩個(gè)圖形路徑是否相等
CGPathGetBoundingBox //返回圖形路徑中包含所有點(diǎn)的包圍盒
CGPathGetPathBoundingBox //返回圖形路徑的邊界框
CGPathGetCurrentPoint //返回當(dāng)前點(diǎn)的路徑
CGPathGetTypeID //返回Quartz圖形路徑的核心基礎(chǔ)類(lèi)型的標(biāo)識(shí)符

CGPathIsEmpty //指示路徑是否為空
CGPathIsRect //圖形路徑指示是否代表一個(gè)矩形
CGPathContainsPoint //檢查一個(gè)點(diǎn)是否在圖形路徑中

與CGContext關(guān)聯(lián)的Path總結(jié)

點(diǎn)&線(xiàn)

注意

  1. AddLineToPoint實(shí)現(xiàn)方式在線(xiàn)條alpha為1,即不透明的時(shí)候和AddLines一樣,而且是實(shí)時(shí)畫(huà)線(xiàn)。
  2. 但是當(dāng)線(xiàn)條半透明的時(shí)候,AddLines在一條線(xiàn)自身重疊時(shí)不會(huì)透明度重疊。
  3. 而AddLineToPoint卻會(huì)導(dǎo)致透明度重疊,且move touch的點(diǎn)出也會(huì)出現(xiàn)透明度重疊,會(huì)顯示成點(diǎn)和點(diǎn)之間透明度正確,點(diǎn)上不透明的問(wèn)題。
//獲取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
    //點(diǎn)(在Context中移動(dòng)畫(huà)筆到(0,0)個(gè)點(diǎn))
CGContextMoveToPoint(context, 0, 0);
    
    //線(xiàn)(畫(huà)筆從上一個(gè)點(diǎn)畫(huà)到(1,1)這個(gè)點(diǎn))
CGContextAddLineToPoint(context, 1, 1);
   
    //添加點(diǎn)的坐標(biāo)
    CGPoint points[] = {
        CGPointMake(0, 0),
        CGPointMake(2, 2),
        CGPointMake(3, 3)
    };
int count = sizeof(points)/sizeof(points[0]);//求出poins長(zhǎng)度
CGContextAddLines(context, points, count);//畫(huà)線(xiàn)
    /*注意
    AddLineToPoint實(shí)現(xiàn)方式在線(xiàn)條alpha為1,即不透明的時(shí)候和AddLines一樣,而且是實(shí)時(shí)畫(huà)線(xiàn)。
     但是當(dāng)線(xiàn)條半透明的時(shí)候,AddLines在一條線(xiàn)自身重疊時(shí)不會(huì)透明度重疊。
     而AddLineToPoint卻會(huì)導(dǎo)致透明度重疊,且move touch的點(diǎn)出也會(huì)出現(xiàn)透明度重疊,會(huì)顯示成點(diǎn)和點(diǎn)之間透明度正確,點(diǎn)上不透明的問(wèn)題。
     */

曲線(xiàn)

一種
void CGContextAddArc (
  CGContextRef c,    
  CGFloat x,             //圓心的x坐標(biāo)
  CGFloat y,  //圓心的x坐標(biāo)
  CGFloat radius,  //圓的半徑
  CGFloat startAngle,    //開(kāi)始弧度
  CGFloat endAngle,  //結(jié)束弧度
  int clockwise          //0表示順時(shí)針,1表示逆時(shí)針
);
假如想創(chuàng)建一個(gè)完整的圓圈,那么 開(kāi)始弧度就是0 結(jié)束弧度是 2pi, 因?yàn)閳A周長(zhǎng)是 2*pi*r.
最后,函數(shù)執(zhí)行完后,current point就被重置為(x,y).
還有一點(diǎn)要注意的是,假如當(dāng)前path已經(jīng)存在一個(gè)subpath,那么這個(gè)函數(shù)執(zhí)行的另外一個(gè)效果是
會(huì)有一條直線(xiàn),從current point到弧的起點(diǎn)
 
第二種
void CGContextAddArcToPoint (
  CGContextRef c,
  CGFloat x1, //端點(diǎn)1的x坐標(biāo)
  CGFloat y1, //端點(diǎn)1的y坐標(biāo)
  CGFloat x2, //端點(diǎn)2的x坐標(biāo)
  CGFloat y2, //端點(diǎn)2的y坐標(biāo)
  CGFloat radius //半徑
);
原理:首先畫(huà)兩條線(xiàn),這兩條線(xiàn)分別是 current point to (x1,y1) 和(x1,y1) to (x2,y2).
這樣就是出現(xiàn)一個(gè)以(x1,y1)為頂點(diǎn)的兩條射線(xiàn),
然后定義半徑長(zhǎng)度,這個(gè)半徑是垂直于兩條射線(xiàn)的,這樣就能決定一個(gè)圓了,更好的理解看下圖,不過(guò)個(gè)人認(rèn)為下圖所標(biāo)的 tangent point 1的位置是錯(cuò)誤的。
最后,函數(shù)執(zhí)行完后,current point就被重置為(x2,y2).
還有一點(diǎn)要注意的是,假如當(dāng)前path已經(jīng)存在一個(gè)subpath,那么這個(gè)函數(shù)執(zhí)行的另外一個(gè)效果是
會(huì)有一條直線(xiàn),從current point到(x1,y1)
Paths - happy dog - 又一個(gè)部落格

傳說(shuō)中的不規(guī)則的曲線(xiàn)

畫(huà)曲線(xiàn),一般是一條直線(xiàn),然后定義幾個(gè)控制點(diǎn),使直線(xiàn)變彎曲。
三次曲線(xiàn)函數(shù)
void CGContextAddCurveToPoint (
  CGContextRef c,
  CGFloat cp1x, //控制點(diǎn)1 x坐標(biāo)
  CGFloat cp1y, //控制點(diǎn)1 y坐標(biāo)
  CGFloat cp2x, //控制點(diǎn)2 x坐標(biāo)
  CGFloat cp2y, //控制點(diǎn)2 y坐標(biāo)
  CGFloat x, //直線(xiàn)的終點(diǎn) x坐標(biāo)
  CGFloat y //直線(xiàn)的終點(diǎn) y坐標(biāo)
);
假如第二個(gè)控制點(diǎn)(cp2x,cp2y)比(cp1x,cp1y) 更接近c(diǎn)urrent point,那么會(huì)形成一個(gè)封閉的曲線(xiàn)
Paths - happy dog - 又一個(gè)部落格
 
二次曲線(xiàn)函數(shù)
void CGContextAddQuadCurveToPoint (
  CGContextRef c,
  CGFloat cpx, //控制點(diǎn) x坐標(biāo)
  CGFloat cpy, //控制點(diǎn) y坐標(biāo)
  CGFloat x, //直線(xiàn)的終點(diǎn) x坐標(biāo)
  CGFloat y //直線(xiàn)的終點(diǎn) y坐標(biāo)
);

裁剪的方法:

CGConextClip;
CGContextEOClip;
CGContextClipToRect;
CGContextClipToRects;
CGContextClipToMask;

圖像繪制

UIGraphicsBeginImageContextWithOptions
UIGraphicsEndImageContext

PDF繪制

UIGraphicsBeginPDFContextToFile(ToData)
UIGraphicsEndPDFContext

翻轉(zhuǎn)屏幕變換:

CGContextTranslateCTM(graphicsContext, 0.0, drawingRect.size.height);
CGContextScaleCTM(graphicsContext, 1.0, -1.0);

** CGPATH &CGCONTEXT相關(guān)聯(lián)的CGPath中的對(duì)應(yīng)關(guān)系**

CGPathCreateMutable = CGContextBeginPath//創(chuàng)建一個(gè)路徑
CGPathMoveToPoint = CGContextMoveToPoint//畫(huà)筆(路徑)從哪里開(kāi)始
CGPathAddLineToPoint = CGContextAddLineToPoint//添加一個(gè)點(diǎn)(線(xiàn))
CGPathAddCurveToPoint = CGContextAddCurveToPoint//創(chuàng)建一個(gè)曲線(xiàn)
CGPathAddEllipseInRect = CGContextAddEllipseInRect//創(chuàng)建一個(gè)橢圓
CGPathAddArc = CGContextAddArc//創(chuàng)建一個(gè)圓形路徑
CGPathAddRect = CGContextAddRect//創(chuàng)建一個(gè)矩形路徑
CGPathCloseSubPath = CGContextCloseSubPath//閉合路徑

UIBezierPath

好了看完了上面的各種函數(shù)是不是頭都大了那么看看我們的UIBezierPath

屬性

CGPath:將UIBezierPath類(lèi)轉(zhuǎn)換成CGPath,類(lèi)似于UIColor的CGColor

empty:只讀類(lèi)型,路徑上是否有有效的元素

bounds:和view的bounds是不一樣的,它獲取path的X坐標(biāo)、Y坐標(biāo)、寬度,但是高度為0

currentPoint:當(dāng)前path的位置,可以理解為path的終點(diǎn)

lineWidth:path寬度

lineCapStyle:path端點(diǎn)樣式,有3種樣式
      kCGLineCapButt:無(wú)端點(diǎn)
      kCGLineCapRound:圓形端點(diǎn)
      kCGLineCapSquare:方形端點(diǎn)(樣式上和kCGLineCapButt是一樣的,但是比kCGLineCapButt長(zhǎng)一點(diǎn))

lineJoinStyle:拐角樣式
      kCGLineJoinMiter:尖角
      kCGLineJoinRound:圓角
      kCGLineJoinBevel:缺角

miterLimit:最大斜接長(zhǎng)度(只有在使用kCGLineJoinMiter是才有效), 邊角的角度越小,斜接長(zhǎng)度就會(huì)越大
為了避免斜接長(zhǎng)度過(guò)長(zhǎng),使用lineLimit屬性限制,如果斜接長(zhǎng)度超過(guò)miterLimit,邊角就會(huì)以KCALineJoinBevel類(lèi)型來(lái)顯示

flatness:彎曲路徑的渲染精度,默認(rèn)為0.6,越小精度越高,相應(yīng)的更加消耗性能。

usesEvenOddFillRule:?jiǎn)坞p數(shù)圈規(guī)則是否用于繪制路徑,默認(rèn)是NO

UIRectCorner:角
  UIRectCornerTopLeft:左上角
  UIRectCornerTopRight:右上角
  UIRectCornerBottomLeft:左下角
  UIRectCornerBottomRight:右下角
  UIRectCornerAllCorners:所有四個(gè)角

UIBezierPath
1.創(chuàng)建UIBezierPath

//矩形路徑(rect矩形的位置和大小)
-(instancetype)bezierPathWithRect:(CGRect)rect:

//創(chuàng)建在rect里的內(nèi)切曲線(xiàn): (參數(shù):rect-矩形的Frame)
+(instancetype)bezierPathWithOvalInRect:(CGRect)rect:

//創(chuàng)建帶有圓角的矩形,當(dāng)矩形變成正圓的時(shí)候,Radius就不再起作用:
//rect:矩形的Frame  cornerRadius:圓角大小)
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius

//圓角的矩形(設(shè)定特定的角為)
/*
rect:矩形的Frame
corners:指定的圓角     
cornerRadii:圓角的大小
*/
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect
                        byRoundingCorners:(UIRectCorner)corners
                              cornerRadii:(CGSize)cornerRadii;

//圓弧
/*
center->圓點(diǎn)
radius->半徑
startAngle->起始位置
endAngle->結(jié)束為止
clockwise->是否順時(shí)針?lè)较?*/

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

//通過(guò)已有路徑創(chuàng)建路徑:
//CGPath->已有路徑
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath

一些對(duì)象方法

-(void)moveToPoint:(CGPoint)point; //移動(dòng)到某一點(diǎn):(point:目標(biāo)位置)
-(void)addLineToPoint:(CGPoint)point; //繪制一條線(xiàn):(point:目標(biāo)位置)
- (void)closePath;//閉合路徑,即在終點(diǎn)和起點(diǎn)連一根線(xiàn)
-(void)appendPath:(UIBezierPath *)bezierPath;//追加路徑
-(UIBezierPath *)bezierPathByReversingPath;//扭轉(zhuǎn)路徑,即起點(diǎn)變成終點(diǎn),終點(diǎn)變成起點(diǎn)
-(void)applyTransform:(CGAffineTransform)transform;//路徑進(jìn)行仿射變換
-(void)fill; //填充;
-(void)stroke; //描邊,路徑創(chuàng)建需要描邊才能顯示出來(lái);
-(void)setStroke;//設(shè)置描邊顏色,需要在設(shè)置后調(diào)用描邊方法:
-(void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; //設(shè)置描邊的混合模式

//設(shè)置描邊的混合模式
//blendMode->混合模式 alpha->透明度
-(void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

//設(shè)置填充的混合模式:
//blendMode:混合模式  alpha:透明度
-(void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

//修改當(dāng)前圖形上下文的繪圖區(qū)域可見(jiàn),隨后的繪圖操作導(dǎo)致呈現(xiàn)內(nèi)容只有發(fā)生在指定路徑的填充區(qū)域
-(void)addClip;


/**
 *  創(chuàng)建虛線(xiàn)
 *  @param pattern C類(lèi)型線(xiàn)性數(shù)據(jù)
 *  @param count   pattern中數(shù)據(jù)個(gè)數(shù)
 *  @param phase   起始位置
 */
- (void)setLineDash:(nullable const CGFloat *)pattern
              count:(NSInteger)count
              phase:(CGFloat)phase;




//清空路徑:
-(void)removeAllPoints;

/**
 *  創(chuàng)建三次貝塞爾曲線(xiàn)
 *  @param endPoint      終點(diǎn)
 *  @param controlPoint1 控制點(diǎn)1
 *  @param controlPoint2 控制點(diǎn)2
 */
-(void)addCurveToPoint:(CGPoint)endPoint
         controlPoint1:(CGPoint)controlPoint1
         controlPoint2:(CGPoint)controlPoint2;


/**
 *  創(chuàng)建二次貝塞爾曲線(xiàn)
 *  @param endPoint     終點(diǎn)
 *  @param controlPoint 控制點(diǎn)
 */
-(void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;


/**
 *  創(chuàng)建圓弧
 *  @param center     圓點(diǎn)
 *  @param radius     半徑
 *  @param startAngle 起始位置
 *  @param endAngle   結(jié)束為止
 *  @param clockwise  是否順時(shí)針?lè)较? */
- (void)addArcWithCenter:(CGPoint)center
                  radius:(CGFloat)radius
              startAngle:(CGFloat)startAngle
                endAngle:(CGFloat)endAngle
               clockwise:(BOOL)clockwise;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,555評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,900評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,629評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,976評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評(píng)論 3 448
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,139評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,411評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,641評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,820評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,233評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,567評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,362評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,604評(píng)論 2 380

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