iOS繪圖總結,ios繪圖

來源:互聯網
上載者:User

iOS繪圖總結,ios繪圖
前言

開發中有項目用到iOS繪圖,去年一直很忙,沒抽出時間來總結,現在算是對去年項目裡繪圖的一個總結,



一、畫圓的幾種方式前言

iOS支援兩套圖形API族:Core Graphics/QuartZ 2D 和OpenGL ES。OpenGL ES是跨平台的圖形API,屬於OpenGL的一個簡化版本。QuartZ 2D是蘋果公司開發的一套API,它是Core Graphics Framework的一部分。需要注意的是:OpenGL ES是API,該介面描述了方法、結構、函數應具有的行為以及應該如何被使用的語義。也就是說它只定義了一套規範,具體的實現由裝置製造商根據規範去做。而往往很多人對介面和實現存在誤解。舉一個不恰當的比喻:上發條的時鐘和裝電池的時鐘都有相同的可視行為,但兩者的內部實現截然不同。因為製造商可以自由的實現Open GL ES,所以不同系統實現的OpenGL ES也存在著巨大的效能差異。 iOS系統自身提供了兩套繪圖的架構,即UIBezierPath 和 Core Graphics。而前者所屬UIKit,其實是對Core Graphics架構關於path的進一步封裝,所以使用起來比較簡單。但是畢竟Core Graphics更接近底層,所以它更加強大。

Core Graphics

Core Graphics API所有的操作都在一個上下文中進行。所以在繪圖之前需要擷取該上下文並傳入執行渲染的函數中。如果你正在渲染一副在記憶體中的圖片,此時就需要傳入圖片所屬的上下文。獲得一個圖形上下文是我們完成繪圖任務的第一步,你可以將圖形上下文理解為一塊畫布。如果你沒有得到這塊畫布,那麼你就無法完成任何繪圖操作。當然,有許多方式獲得一個圖形上下文,這裡我介紹兩種最為常用的擷取方法。

MyView1
- (void) drawRect: (CGRect) rect {    UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];    [[UIColor blueColor] setFill];    [p fill];}
MyView2
- (void) drawRect: (CGRect) rect {    CGContextRef con = UIGraphicsGetCurrentContext();    CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));    CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);    CGContextFillPath(con);}

在UIView子類的drawLayer:inContext:方法中實現繪圖任務。drawLayer:inContext:方法是一個繪製圖層內容的代理方法。為了能夠調用drawLayer:inContext:方法,我們需要設定圖層的代理對象。但要注意,不應該將UIView對象設定為顯示層的委派物件,這是因為UIView對象已經是隱式層的代理對象,再將它設定為另一個層的委派物件就會出問題。輕量級的做法是:編寫負責繪圖形的代理類

MyView3
- (void)drawLayer:(CALayer*)lay inContext:(CGContextRef)con {    UIGraphicsPushContext(con);    UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];    [[UIColor orangeColor] setFill];    [p fill];    UIGraphicsPopContext();}
MyView4
- (void)drawLayer:(CALayer*)lay inContext:(CGContextRef)con {    CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));    CGContextSetFillColorWithColor(con, [UIColor orangeColor].CGColor);    CGContextFillPath(con);}

建立一個圖片類型的上下文。調用UIGraphicsBeginImageContextWithOptions函數就可獲得用來處理圖片的圖形上下文。利用該上下文,你就可以在其上進行繪圖,並產生圖片。調用UIGraphicsGetImageFromCurrentImageContext函數可從當前上下文中擷取一個UIImage對象。記住在你所有的繪圖操作後別忘了調用UIGraphicsEndImageContext函數關閉圖形上下文。

MyImageView1
- (void) awakeFromNib {    [super awakeFromNib];    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100), NO, 0);    CGContextRef con = UIGraphicsGetCurrentContext();    CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));    CGContextSetFillColorWithColor(con, [UIColor yellowColor].CGColor);    CGContextFillPath(con);    UIImage* im = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    self.image = im;}
MyImageView2
- (void) awakeFromNib {    [super awakeFromNib];    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100), NO, 0);    UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];    [[UIColor yellowColor] setFill];    [p fill];    UIImage* im = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    self.image = im;}

繪圖的步驟總結:1、 擷取上下文 2、 建立路徑(描述路徑) 3、把路徑添加到上下文 4、 渲染上下文關於drawRect方法

1、通常在drawRect裡面繪圖,只有在這個方法裡面才能擷取到跟 View的layer相關聯的圖形上下文

2、drawRect在以下情況下會被調用:

1、如果在UIView初始化時沒有設定rect大小,將直接導致drawRect不被自動調用。drawRect調用是在Controller->loadView, Controller->viewDidLoad 兩方法之後掉用的.所以不用擔心在控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設定一些值給View(如果這些View draw的時候需要用到某些變數值).

2、該方法在調用sizeToFit後被調用,所以可以先調用sizeToFit計算出size。然後系統自動調用drawRect: 方法。

3、通過設定contentMode屬性值為UIViewContentModeRedraw。那麼將在每次設定或更改frame的時候自動調用drawRect:。

4、直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,但是有個前提條件是rect不能為0。
以上1,2推薦;而3,4不提倡

3、drawRect方法使用注意點:

1、若使用UIView繪圖,只能在drawRect:方法中擷取相應的contextRef並繪圖。如果在其他方法中擷取將擷取到一個invalidate的ref並且不能用於畫圖。drawRect:方法不能手動顯示調用,必須通過調用setNeedsDisplay 或者 setNeedsDisplayInRect,讓系統自動調該方法。 2、若使用CAlayer繪圖,只能在drawInContext: 中(類似於drawRect)繪製,或者在delegate中的相應方法繪製。同樣也是調用setNeedDisplay等間接調用以上方法 3、若要即時畫圖,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用setNeedsDisplay即時重新整理螢幕

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.