iOS 繪圖

轉(zhuǎn)自:iOS繪圖—— UIBezierPath 和 Core Graphics
繪圖進(jìn)階請(qǐng)參考:繪圖

前言

iOS系統(tǒng)本身提供了兩套繪圖的框架,即UIBezierPath 和 Core Graphics。而前者所屬UIKit,其實(shí)是對(duì)Core Graphics框架關(guān)于path的進(jìn)一步封裝,所以使用起來(lái)比較簡(jiǎn)單。但是畢竟Core Graphics更接近底層,所以它更加強(qiáng)大。

UIBezierPath

可以創(chuàng)建基于矢量的路徑,例如橢圓或者矩形,或者有多個(gè)直線和曲線段組成的形狀。
使用UIBezierPath,你只能在當(dāng)前上下文中繪圖,所以如果你當(dāng)前處于UIGraphicsBeginImageContextWithOptions函數(shù)或drawRect:方法中,你就可以直接使用UIKit提供的方法進(jìn)行繪圖。如果你持有一個(gè)context:參數(shù),那么使用UIKit提供的方法之前,必須將該上下文參數(shù)轉(zhuǎn)化為當(dāng)前上下文。幸運(yùn)的是,調(diào)用UIGraphicsPushContext 函數(shù)可以方便的將context:參數(shù)轉(zhuǎn)化為當(dāng)前上下文,記住最后別忘了調(diào)用UIGraphicsPopContext函數(shù)恢復(fù)上下文環(huán)境。

簡(jiǎn)言之:我們一般使用UIBezierPath都是在重寫的drawRecrt方法這種情形。其繪圖的步驟是這樣的:

  1. 重寫drawRect方法。但不需要我們自己獲取當(dāng)前上下文context;
  2. 創(chuàng)建相應(yīng)圖形的UIBezierPath對(duì)象,并設(shè)置一些修飾屬性;
  3. 渲染,完成繪制。
// 1.重寫drawRect方法
- (void)drawRect:(CGRect)rect {
    // 2.創(chuàng)建圖形相應(yīng)的UIBezierPath對(duì)象
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 50)];
    // 設(shè)置一些修飾屬性
    path.lineWidth = 28.0;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    UIColor *color = [UIColor colorWithRed:0 green:0 blue:0.7 alpha:1];
    [color set];
    
    // 4.渲染,完成繪制
    [path stroke];
}

效果如下:



Core Graphics

這是一個(gè)繪圖專用的API族,它經(jīng)常被稱為QuartZ或QuartZ 2D。Core Graphics是iOS上所有繪圖功能的基石,包括UIKit。

要搞清楚Core Graphics就要搞清楚下面幾個(gè)問(wèn)題:

1. 繪圖需要 CGContextRef

CGContextRef即圖形上下文。可以這么理解,我們繪圖是需要一個(gè)載體或者說(shuō)輸出目標(biāo),它用來(lái)顯示繪圖信息,并且決定繪制的東西輸出到哪個(gè)地方??梢孕蜗蟮谋扔?code>context就像一個(gè)“畫(huà)板”,我們得把圖形繪制到這個(gè)畫(huà)板上。所以,繪圖必須要先有context。

2. 怎么拿到context?

第一種方法是利用cocoa為你生成的圖形上下文。當(dāng)你子類化了一個(gè)UIView并實(shí)現(xiàn)了自己的drawRect:方法后,一旦drawRect:方法被調(diào)用,Cocoa就會(huì)為你創(chuàng)建一個(gè)圖形上下文,此時(shí)你對(duì)圖形上下文的所有繪圖操作都會(huì)顯示在UIView上。

第二種方法就是創(chuàng)建一個(gè)圖片類型的上下文。調(diào)用UIGraphicsBeginImageContextWithOptions函數(shù)就可獲得用來(lái)處理圖片的圖形上下文。利用該上下文,你就可以在其上進(jìn)行繪圖,并生成圖片。調(diào)用UIGraphicsGetImageFromCurrentImageContext函數(shù)可從當(dāng)前上下文中獲取一個(gè)UIImage對(duì)象。記住在你所有的繪圖操作后別忘了調(diào)用UIGraphicsEndImageContext函數(shù)關(guān)閉圖形上下文。

簡(jiǎn)言之:

  • 重寫UIView的drawRect方法,在該方法里便可得到context;
  • 調(diào)用UIGraphicsBeginImageContextWithOptions方法得到context;

3. 注意

并不是說(shuō)一提到繪圖,就一定得重寫drawRect方法,只是因?yàn)橥ǔG闆r下我們一般采用在drawRect方法里獲取context這種方式。

4. drawRect方法什么時(shí)候觸發(fā)

  • 1.當(dāng)view第一次顯示到屏幕上時(shí);
  • 2.當(dāng)調(diào)用view的setNeedsDisplay或者setNeedsDisplayInRect:方法時(shí)。

步驟:

  • 1.先在drawRect方法中獲得上下文context;
  • 2.繪制圖形(線,圖形,圖片等);
  • 3.設(shè)置一些修飾屬性;
  • 4.渲染到上下文,完成繪圖。
- (void)drawRect:(CGRect)rect {
    // 1.獲取上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // --------------------------實(shí)心圓
    // 2.畫(huà)圖
    CGContextAddEllipseInRect(context, CGRectMake(10, 10, 50, 50));
    [[UIColor greenColor] set];
    // 3.渲染
    CGContextFillPath(context);
    
    // --------------------------空心圓
    
    CGContextAddEllipseInRect(context, CGRectMake(70, 10, 50, 50));
    [[UIColor redColor] set];
    CGContextStrokePath(context);
    
    
    
    // --------------------------橢圓
    //畫(huà)橢圓和畫(huà)圓方法一樣,橢圓只是設(shè)置不同的長(zhǎng)寬
    CGContextAddEllipseInRect(context, CGRectMake(130, 10, 100, 50));
    [[UIColor purpleColor] set];
    CGContextFillPath(context);
    
    
    
    // --------------------------直線
    CGContextMoveToPoint(context, 20, 80); // 起點(diǎn)
    CGContextAddLineToPoint(context, self.frame.size.width-10, 80); //終點(diǎn)
    //    CGContextSetRGBStrokeColor(ctx, 0, 1.0, 0, 1.0); // 顏色
    [[UIColor redColor] set]; // 兩種設(shè)置顏色的方式都可以
    CGContextSetLineWidth(context, 2.0f); // 線的寬度
    CGContextSetLineCap(context, kCGLineCapRound); // 起點(diǎn)和重點(diǎn)圓角
    CGContextSetLineJoin(context, kCGLineJoinRound); // 轉(zhuǎn)角圓角
    CGContextStrokePath(context); // 渲染(直線只能繪制空心的,不能調(diào)用CGContextFillPath(ctx);)
    
    
    
    // --------------------------三角形
    CGContextMoveToPoint(context, 10, 150); // 第一個(gè)點(diǎn)
    CGContextAddLineToPoint(context, 60, 100); // 第二個(gè)點(diǎn)
    CGContextAddLineToPoint(context, 100, 150); // 第三個(gè)點(diǎn)
    [[UIColor purpleColor] set];
    CGContextClosePath(context);
    CGContextStrokePath(context);
    
    
    
    // --------------------------矩形
    CGContextAddRect(context, CGRectMake(20, 170, 100, 50));
    [[UIColor orangeColor] set];
    //    CGContextStrokePath(ctx); // 空心
    CGContextFillPath(context);
    
    
    
    // --------------------------圓弧
    CGContextAddArc(context, 200, 170, 50, M_PI, M_PI_4, 0);
    CGContextClosePath(context);
    CGContextFillPath(context);
    
    
    // --------------------------文字
    NSString *str = @"你在紅樓,我在西游";
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName] = [UIColor whiteColor]; // 文字顏色
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:14]; // 字體
    
    [str drawInRect:CGRectMake(20, 250, 300, 30) withAttributes:dict];
    
    
    // --------------------------圖片
    UIImage *img = [UIImage imageNamed:@"yingmu"];
    //    [img drawAsPatternInRect:CGRectMake(20, 280, 300, 300)]; // 多個(gè)平鋪
    //    [img drawAtPoint:CGPointMake(20, 280)]; // 繪制到指定點(diǎn),圖片有多大就顯示多大
    [img drawInRect:CGRectMake(20, 280, 80, 80)]; // 拉伸
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容