Core Graphics架構,coregraphics架構

來源:互聯網
上載者:User

Core Graphics架構,coregraphics架構

在iOS中常用的架構是Quartz 2D,它是Core Graphics架構的一部分,是一個強大的二維映像繪製引擎。我們日常開發所用到的UIKit的組件都是由Core Graphics架構進行繪製的。當我們匯入UIKit架構時,會自動匯入Core Graphics架構。

在iOS中繪圖一般分為以下幾個步驟:

1.擷取繪圖上下文

2.建立並設定路徑

3.將路徑添加到上下文

4.設定內容相關的狀態

5.繪製路徑

6.釋放路徑

圖形上下文中CGContextRef代表圖形輸出裝置,也就是繪製的位置,包含繪製圖形的一些裝置資訊,Quartz 2D中的所有對象,都最終都必須要添加到圖形上下文,這樣一來,我們在繪製圖形的時候就不必關係具體的裝置資訊。

基本圖形繪製

在UIKit中,已經預設為我們準備好一個圖形內容物件,在UIView的drawrect方法中,我們可以通過通過UIKit封裝函數UIGraphicsGetCurrentContext()方法擷取到圖形上下文(註:在其它方法中無法擷取),然後只需要按照繪製圖形的步驟一步步執行即可,下面重寫view的drawrect方法,在view上添加兩條線:

override func draw(_ rect: CGRect) {        //  1.擷取圖形內容物件        let contextRef = UIGraphicsGetCurrentContext()                //  2.建立路徑對象        let path = CGMutablePath()        path.move(to: CGPoint(x: 10, y: 10))        path.addLine(to: CGPoint(x: 100, y: 100))                //  這一段代碼是繪製曲線,lengths 表示的是 虛線的每段長度為5,每段間距為1,phase 如果填2,則表示虛線的第一個線段的長度為 5 - 2        let a : CGFloat = 5        let b : CGFloat = 1        let lengths = [a,b]        contextRef?.setLineDash(phase: 2, lengths: lengths)            path.move(to: CGPoint(x: 5, y: 20))        path.addLine(to: CGPoint(x: 100, y: 100))                //  3.添加到映像上下文        contextRef?.addPath(path)                //  4.設定圖形上下文狀態屬性        contextRef?.setStrokeColor(UIColor.red.cgColor)     //  邊框顏色        contextRef?.setFillColor(UIColor.blue.cgColor)      //  填充顏色,可以在封閉路徑中使用        contextRef?.setLineWidth(2)                         //  線條寬度        //  5.繪製        contextRef?.strokePath()    }
封閉圖形繪製

上面的繪圖方式顯得有些麻煩,其實Core Graphics內部對建立路徑對象添加到上下文這兩步操作進行了封裝,可以一步完成,下面我們用線段繪製一個簡單的矩形:

//  1.擷取映像上下文        let contextRef = UIGraphicsGetCurrentContext()                //  2.開始繪製一個正方形        contextRef?.move(to: CGPoint(x: 10, y: 10))        contextRef?.addLine(to: CGPoint(x: 110, y: 10))        contextRef?.addLine(to: CGPoint(x: 110, y: 110))        contextRef?.addLine(to: CGPoint(x: 10, y: 110))        // 第四條線我們可以直接使用這個方法繪製        contextRef?.closePath()                //  3.設定相關狀態        contextRef?.setLineWidth(2)        contextRef?.setStrokeColor(UIColor.red.cgColor)        contextRef?.setFillColor(UIColor.blue.cgColor)                        //  4.開始繪製 .既有邊框(路徑),又有填充        contextRef?.drawPath(using: .fillStroke)
繪製一個矩形

上面的代碼已經相對來說簡化了不少,除了路徑之外,矩形,橢圓也都有相應的繪製方法。

// ----------- 使用addRect方法繪製 ------------                //  1.擷取映像上下文        let contextRef = UIGraphicsGetCurrentContext()        //  2.路徑        contextRef?.addRect(CGRect(x: 10, y: 10, width: 100, height: 100))        //  3.狀態        contextRef?.setFillColor(UIColor.blue.cgColor)        contextRef?.setStrokeColor(UIColor.red.cgColor)        //  4.繪製        contextRef?.drawPath(using: .fillStroke)

  

// ----------- 使用UI方法繪製 ------------                //  繪製一個填充色為紅色的矩形        UIColor.red.setFill()        UIRectFill(CGRect(x: 10, y: 10, width: 100, height: 100))                //  繪製一個邊框為藍色的矩形        UIColor.blue.setStroke()        UIRectFrame(CGRect(x: 20, y: 20, width: 100, height: 100))
 繪製一個圓
//  1.擷取圖形上下文        let contextRef = UIGraphicsGetCurrentContext()                //  2.先規定一個矩形        let rect = CGRect(x: 10, y: 10, width: 100, height: 100)                //  3.添加內切圓        contextRef?.addEllipse(in: rect)    //  內切圓                //  4.設定填充色        contextRef?.setFillColor(UIColor.red.cgColor)                //  5.繪製        contextRef?.drawPath(using: .fill)
 繪製一個弧形
//  1.擷取圖形上下文        let contextRef = UIGraphicsGetCurrentContext()                //  2.添加弧度        let center = CGPoint(x: 100, y: 100)    //  圓心座標
     contextRef.moveTo(center)         //  加上這句代碼就可以繪製出一個扇形 let radius : CGFloat = 50 // 半徑 let startAngle : CGFloat = 0 // 開始弧度制 let endAngle : CGFloat = CGFloat(Double.pi/4) // 結束弧度制 let clockwise = true // 是否逆時針 contextRef?.addArc(center: center, radius: CGFloat(radius), startAngle: startAngle, endAngle: endAngle, clockwise: clockwise) // 3.設定填充色 contextRef?.setFillColor(UIColor.red.cgColor) // 4.繪製 contextRef?.drawPath(using: .fill)

  

 

漸層色填充

在上面的Demo中我們可以看到如何設定填充顏色,事實上很多時候純色的填充並不能滿足我們的足球,例如有的時候我們需要繪製一些圖形可能需要設定一個漂亮的背景,如果UI MM不給切圖的話,這個時候我們可能就會選擇漸層填充的方式。

Quartz 2D的漸層方式分為兩種:

a.線性漸層線:漸層色以直線方式從開始位置逐漸向結束位置漸層

b.放射狀漸層:以中心點為圓心從起始漸層色向四周輻射,直到終止漸層色。

要做漸層則必須先設定從開始位置到結束位置的漸層顏色,UI MM可定對於漸層色設定並不陌生,只需要在指定位置指定不同的顏色,剩下的事情交給系統處理就行。如,在起始位置,3/10位置,結束位置指定了三種顏色就形成了由三種顏色組成的漸層色。

另外,在iOS中繪製漸層還需要注意一點就是指定色彩空間,所謂色彩空間就是不同顏色在不同的維度上取值,最終組成一種顏色的過程。就拿RGB來說,如果將紅色,綠色,藍色看成是x、y、z軸座標系,那麼在三個座標上分別取0-255範圍內的不同值則可以組成各類顏色。當然,不同色彩空間的座標系也是不同的,也就是說顏色表示的方式是不同的,常用的色彩空間除了RGB還有CMYK(印刷業常用這種顏色模式)、Gray.

在使用Quartz 2D繪圖時我們的顏色除了使用常規的方法(如CGContextSetRGBFillColor(CGContextRef context, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)方法)設定RGB和透明度之外,有時還會遇到顏色參數是一個數組情況。如使用色彩空間填充時用到的CGContextSetFillColor(CGContextRef context, const CGFloat *components)方法,這個時候components數組中具體是如何儲存顏色就要根據色彩空間而定,如果色彩空間使用RGB,則數組中的元素四個為一組,分別是red、green、blue、alpha;如果使用的是CMYK色彩空間,那麼數組中的元素五個為一組,分別是cyan、magenta、yellow、black、alpha。

下面,分別使用一下這兩種漸層的方式:

1.線性漸層

override func draw(_ rect: CGRect) {                //  擷取上下文        let contextRef = UIGraphicsGetCurrentContext()                //  使用RGB色彩空間        let colorSpace = CGColorSpaceCreateDeviceRGB()                //  指定漸層色        /*         colorSpace : 色彩空間         colorComponents : 顏色數組,由於指定了為RGB色彩空間,那麼四個數組元素就表示一個顏色(red\green\blue\alpha),如果有三個顏色,那麼這個數組中就要有 3 * 4 個元素。         locations : 顏色所在的位置 0 - 1,這個數組的個數不小於顏色的個數         count : 漸層的個數,等於locations的count         */                let colorComponents : [CGFloat] = [248.0/255.0,86.0/255.0,86.0/255.0,1,                                           249.0/255.0,127.0/255.0,127.0/255.0,1,                                           1.0,1.0,1.0,1.0]        let locations : [CGFloat] = [0,0.3,1.0]                let gradient = CGGradient(colorSpace: colorSpace, colorComponents: colorComponents, locations: locations, count: 3)                //  繪製線性色彩坡形        /*        start : 起始座標        end : 結束座標         options :繪製方式,kCGGradientDrawsBeforeStartLocation 開始位置之前就進行繪製,到結束位置之後不再繪製,         kCGGradientDrawsAfterEndLocation開始位置之前不進行繪製,到結束點之後繼續填充        */        contextRef?.drawLinearGradient(gradient!, start: CGPoint(x : 0, y : 20), end: CGPoint(x : 0, y : self.frame.size.height - 40), options: .drawsBeforeStartLocation)    }

2.放射狀漸層

override func draw(_ rect: CGRect) {                //  擷取上下文        let contextRef = UIGraphicsGetCurrentContext()                //  使用RGB色彩空間        let colorSpace = CGColorSpaceCreateDeviceRGB()                //  指定漸層色        /*         colorSpace : 色彩空間         colorComponents : 顏色數組,由於指定了為RGB色彩空間,那麼四個數組元素就表示一個顏色(red\green\blue\alpha),如果有三個顏色,那麼這個數組中就要有 3 * 4 個元素。         locations : 顏色所在的位置 0 - 1,這個數組的個數不小於顏色的個數         count : 漸層的個數,等於locations的count         */                let colorComponents : [CGFloat] = [248.0/255.0,86.0/255.0,86.0/255.0,1,                                           249.0/255.0,127.0/255.0,127.0/255.0,1,                                           1.0,1.0,1.0,1.0]        let locations : [CGFloat] = [0,0.3,1.0]                let gradient = CGGradient(colorSpace: colorSpace, colorComponents: colorComponents, locations: locations, count: 3)                /*繪製放射狀漸層         context:圖形上下文         gradient:漸層色         startCenter:起始點位置         startRadius:起始半徑(通常為0,否則在此半徑範圍內容無任何填充)         endCenter:終點位置(通常和起始點相同,否則會有位移)         endRadius:終點半徑(也就是漸層的擴散長度)         options:繪製方式,kCGGradientDrawsBeforeStartLocation 開始位置之前就進行繪製,但是到結束位置之後不再繪製,         kCGGradientDrawsAfterEndLocation開始位置之前不進行繪製,但到結束點之後繼續填充         */        let center = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)        contextRef?.drawRadialGradient(gradient!, startCenter: center, startRadius: 0, endCenter: center, endRadius: 30, options: .drawsAfterEndLocation)    }

 3.漸層填充

上面我們只是繪製漸層到圖形上下文,實際開發中有時候我們還需要填充對應的漸層色,例如現在繪製了一個矩形,如何填充成漸層色呢?在此可以利用漸層裁切來完成(當然利用層CALayer更加方便),特別說明一下地區裁切並不僅僅適用於漸層填充,對於其他圖形繪製仍然適用,並且注意裁切只能限於矩形裁切。

override func draw(_ rect: CGRect) {                //  擷取上下文        let contextRef = UIGraphicsGetCurrentContext()                //  使用RGB色彩空間        let colorSpace = CGColorSpaceCreateDeviceRGB()                //裁切還可以使用UIKit中對應的方法        UIRectClip(CGRect(x: 0, y: 20, width: self.frame.size.width, height: self.frame.size.height - 40))                //  指定漸層色        /*         colorSpace : 色彩空間         colorComponents : 顏色數組,由於指定了為RGB色彩空間,那麼四個數組元素就表示一個顏色(red\green\blue\alpha),如果有三個顏色,那麼這個數組中就要有 3 * 4 個元素。         locations : 顏色所在的位置 0 - 1,這個數組的個數不小於顏色的個數         count : 漸層的個數,等於locations的count         */                let colorComponents : [CGFloat] = [248.0/255.0,86.0/255.0,86.0/255.0,1,                                           249.0/255.0,127.0/255.0,127.0/255.0,1,                                           1.0,1.0,1.0,1.0]        let locations : [CGFloat] = [0,0.3,1.0]                let gradient = CGGradient(colorSpace: colorSpace, colorComponents: colorComponents, locations: locations, count: 3)                //  繪製線性色彩坡形        /*        start : 起始座標        end : 結束座標         options :繪製方式,kCGGradientDrawsBeforeStartLocation 開始位置之前就進行繪製,到結束位置之後不再繪製,         kCGGradientDrawsAfterEndLocation開始位置之前不進行繪製,到結束點之後繼續填充        */        contextRef?.drawLinearGradient(gradient!, start: CGPoint(x : 0, y : 20), end: CGPoint(x : 0, y : self.frame.size.height - 40), options: .drawsBeforeStartLocation)    }

  

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.