最近在開發(fā)一款圖片相關(guān)的App,想要實現(xiàn)某些炫酷的功能湃鹊,在開發(fā)過程中遇到了不少的坑测柠,也參考了github上不少優(yōu)秀的代碼水醋。筆者認為,深入處理圖片和UI相關(guān)的技術(shù),最終總是繞不開UICoreGraphics框架,遂把自己編寫代碼和閱讀文檔的經(jīng)驗記錄下來與讀者分享。
1. 為什么需要UICoreGraphics
在iOS開發(fā)中峰尝,編寫頁面的代碼非常簡單,只需要創(chuàng)建需要的UIButton, UILabel以及UITableView等控件就可以實現(xiàn)頁面代碼的編寫收恢,甚至開發(fā)者只需要使用Xib和StoryBoard來拖拉控件即可布局頁面武学。可以說伦意,這都是UIKit的功勞火窒,因為UIKit友好地封裝了這些接口,開發(fā)者才能快速驮肉、高效地編寫頁面代碼熏矿。
但這往往是不夠的,如果我們想要自定義UI組件离钝,這時候就需要更深層次的知識了票编,UICoreGraphics就是這樣一個很重要的知識點。
UICoreGraphics也被成為QuartZ或Quartz 2D卵渴,它是iOS上用來繪制圖形的基石慧域,包括UIKit等框架都是基于UICoreGraphics封裝實現(xiàn)的。有時浪读,開發(fā)者會使用UIBezierPath來繪制自定義的UI組件昔榴,然而UIBezierPath也是通過封裝UICoreGraphics來實現(xiàn)的,所以深入學(xué)習(xí)UICoreGraphics框架真的很有必要瑟啃。
2. 怎樣使用UICoreGraphics
在使用UICoreGraphics之前论泛,我們得先了解繪圖上下文context
的概念,讀者可以把context
當(dāng)作一個空白的畫板蛹屿,我們自定義的樣式、動畫等都是在這個畫板上完成的岩榆。為了使用繪圖上下文context
错负,可以使用如下兩種方式,
- 在自定義view的
-drawRect
中獲取 - 通過
UIGraphicsBeginImageContextWithOptions
獲取
簡單來說勇边,第1種方法是通過重寫UIView的-drawRect
方法犹撒,在該方法內(nèi)獲取繪圖上下文context
;第2種方法通過let context = UIGraphicsBeginImageContextWithOptions
獲取繪圖上下文context
粒褒。
提示:UIView的
-drawRect
方法在UIView對象第一次顯示在屏幕上時會自動執(zhí)行识颊;我們也可以調(diào)用UIView對象的-setNeedDisplay
或setNeedsDisplayInRect
來主動出發(fā)該方法的執(zhí)行。
3. 在swift中使用UICoreGraphics更加簡單
在OC中使用UICoreGraphics,都是使用C語言的語法來調(diào)用UICoreGraphics的api祥款,代碼不僅啰嗦而且容易出錯清笨。好在swift 3.0對UICoreGraphics的語法進行了大大地簡化,我們可以通過創(chuàng)建對象的方式來使用UICoreGraphics刃跛。
使用UICoreGraphics進行UIView的自定義繪制抠艾,總結(jié)來說就是如下的步驟,
- (1) 獲取繪圖上下文
context
桨昙,可以在UIView的-drawRect
中獲取检号,或通過UIGraphicsBeginImageContextWithOptions
獲取 - (2) 繪制需要的圖形、文字蛙酪、圖片等
- (3) 設(shè)置對應(yīng)的屬性齐苛,例如顏色,粗細桂塞,字體等
- (4) 渲染到繪圖上下文凹蜂,完成繪圖
下面就用swift語言,寫一個簡單的demo藐俺,如下代碼所示炊甲,
import UIKit
class CustomView: UIView {
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
let context = UIGraphicsGetCurrentContext()
// 畫一個圓
context?.addEllipse(in: CGRect(x: 20, y: 20, width: 88, height: 88))
UIColor.green.set()
// 渲染
context?.fillPath()
// 畫一個空心的園
context?.addEllipse(in: CGRect(x: 20, y: 150, width: 100, height: 100))
UIColor.red.set()
context?.strokePath()
// 橢圓
context?.addEllipse(in: CGRect(x: 20, y: 300, width: 100, height: 50))
UIColor.purple.set()
context?.fillPath()
// 直線
context?.move(to: CGPoint(x: 30, y: 80))
context?.addLine(to: CGPoint(x: 90, y: 100))
UIColor.blue.set()
context?.setLineWidth(2.0)
context?.setLineCap(.round)
context?.setLineJoin(.round)
context?.strokePath()
// 三角形
context?.move(to: CGPoint(x: 10, y: 150))
context?.addLine(to: CGPoint(x: 60, y: 100))
context?.addLine(to: CGPoint(x: 100, y: 150))
UIColor.purple.set()
context?.closePath()
context?.strokePath()
// 矩形
context?.addRect(CGRect(x: 20, y: 170, width: 100, height: 50))
// UIColor.orange.set()
// context?.fillPath()
UIColor.red.set()
context?.strokePath()
// 繪制文字
// ....
// 繪制圖片
// ...
}
}
我們也可以使用UICoreGraphics來繪制文字
和圖片
內(nèi)容,這里筆者不再贅述欲芹。
寫在最后
以上的內(nèi)容只是UICoreGraphics最基礎(chǔ)最簡單的內(nèi)容卿啡,但讀者應(yīng)該注重這些基礎(chǔ)知識的積累,因為千里之行菱父,始于足下颈娜。筆者就是在開發(fā)圖片處理的App時,由于基礎(chǔ)薄弱浙宜,看開源代碼都沒有頭緒官辽,所以才回過頭來鞏固這些基礎(chǔ)知識。
后面粟瞬,筆者會逐漸深入學(xué)習(xí)UICoreGraphics以及iOS圖片處理技術(shù)同仆,有新的心得和經(jīng)驗,筆者也會積極與讀者分享裙品,敬請期待^^俗批。