一填帽、drawRect
這個(gè)方法是用來重繪的评也,一般為了降低視圖層級(jí)瞳脓,會(huì)選擇在這里進(jìn)行繪制悔政。
-
drawRect
在以下情況下會(huì)被調(diào)用:
- 如果在UIView初始化時(shí)沒有設(shè)置rect大小,將直接導(dǎo)致
drawRect
不被自動(dòng)調(diào)用桥言。drawRect
調(diào)用是在Controller->loadView
,Controller->viewDidLoad
兩方法之后調(diào)用的.所以不用擔(dān)心在控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設(shè)置一些值給View(如果這些View draw的時(shí)候需要用到某些變量值). - 該方法在調(diào)用
sizeToFit
后被調(diào)用萌踱,所以可以先調(diào)用sizeToFit
計(jì)算出size。然后系統(tǒng)自動(dòng)調(diào)用drawRect:
方法号阿。 - 通過設(shè)置
contentMode
屬性值為UIViewContentModeRedraw
并鸵。那么將在每次設(shè)置或更改frame的時(shí)候自動(dòng)調(diào)用drawRect:
。 - 直接調(diào)用
setNeedsDisplay
扔涧,或者setNeedsDisplayInRect:
觸發(fā)drawRect:园担,但是有個(gè)前提條件是rect不能為0。
以上1,2推薦枯夜;而3,4不提倡
使用注意點(diǎn):
- 若使用UIView繪圖弯汰,只能在
drawRect:
方法中獲取相應(yīng)的contextRef
并繪圖。如果在其他方法中獲取將獲取到一個(gè)invalidate
的ref并且不能用于畫圖湖雹。drawRect:
方法不能手動(dòng)顯示調(diào)用咏闪,必須通過調(diào)用setNeedsDisplay
或者setNeedsDisplayInRect
,讓系統(tǒng)自動(dòng)調(diào)該方法摔吏。- 若使用CALayer繪圖鸽嫂,只能在
drawInContext:
中(類似于drawRect
)繪制,或者在delegate中的相應(yīng)方法繪制征讲。同樣也是調(diào)用setNeedDisplay
等間接調(diào)用以上方法- 若要實(shí)時(shí)畫圖据某,不能使用gestureRecognizer,只能使用touchbegan等方法來掉用
setNeedsDisplay
實(shí)時(shí)刷新屏幕.- 繪圖時(shí)一定是layout之后稳诚,不必?fù)?dān)心frame的問題
sizeToFit
- (void)sizeToFit
根據(jù)子視圖的大小位置哗脖,調(diào)整視圖,使其恰好圍繞子視圖, 也就是說自動(dòng)適應(yīng)子視圖的大小才避,只顯示子視圖
- (CGSize)sizeThatFits:(CGSize)size
讓視圖計(jì)算最適合子視圖的大小橱夭,即能把全部子視圖顯示出來所需要的最小的size
-
sizeToFit不
應(yīng)該在子類中被重寫,應(yīng)該重寫sizeThatFits
桑逝。sizeToFit
會(huì)自動(dòng)調(diào)用sizeThatFits
方法棘劣; -
sizeThatFits
傳入的參數(shù)是receiver
當(dāng)前的size
,返回一個(gè)適合的size
-
sizeToFit
可以被手動(dòng)直接調(diào)用sizeToFit
和sizeThatFits
方法都沒有遞歸楞遏,對(duì)subviews也不負(fù)責(zé)茬暇,只負(fù)責(zé)自己
重繪
-drawRect:(CGRect)rect方法:重寫此方法预鬓,執(zhí)行重繪任務(wù)
-setNeedsDisplay方法:標(biāo)記為需要重繪,異步調(diào)用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:標(biāo)記為需要局部重繪
layoutSubviews對(duì)subviews重新布局
layoutSubviews方法調(diào)用先于drawRect
setNeedsLayout在receiver標(biāo)上一個(gè)需要被重新布局的標(biāo)記沧奴,在系統(tǒng)runloop的下一個(gè)周期自動(dòng)調(diào)用layoutSubviews
layoutIfNeeded方法如其名滔吠,UIKit會(huì)判斷該receiver是否需要layout.根據(jù)Apple官方文檔,layoutIfNeeded方法應(yīng)該是這樣的
layoutIfNeeded遍歷的不是superview鏈肆资,應(yīng)該是subviews鏈
drawRect是對(duì)receiver的重繪犯犁,能獲得context。
總之,理解view布局的過程入桂,可以幫助你理解View顯示的相關(guān)問題蜘腌,解決一些界面問題倘潜,合理使用以上方法對(duì)你自定義控件也有很大的幫助。
-drawRect:(CGRect)rect方法:重寫此方法澜掩,執(zhí)行重繪任務(wù)
-setNeedsDisplay方法:標(biāo)記為需要重繪乔妈,異步調(diào)用drawRect
-setNeedsDisplayInRect:(CGRect)invalidRect方法:標(biāo)記為需要局部重繪
sizeToFit會(huì)自動(dòng)調(diào)用sizeThatFits方法;
sizeToFit不應(yīng)該在子類中被重寫氓皱,應(yīng)該重寫sizeThatFits
sizeThatFits傳入的參數(shù)是receiver當(dāng)前的size路召,返回一個(gè)適合的size
sizeToFit可以被手動(dòng)直接調(diào)用
sizeToFit和sizeThatFits方法都沒有遞歸勃刨,對(duì)subviews也不負(fù)責(zé),只負(fù)責(zé)自己
layoutSubviews對(duì)subviews重新布局
layoutSubviews方法調(diào)用先于drawRect
setNeedsLayout在receiver標(biāo)上一個(gè)需要被重新布局的標(biāo)記股淡,在系統(tǒng)runloop的下一個(gè)周期自動(dòng)調(diào)用layoutSubviews
layoutIfNeeded方法如其名身隐,UIKit會(huì)判斷該receiver是否需要layout
layoutIfNeeded遍歷的不是superview鏈,應(yīng)該是subviews鏈
drawRect是對(duì)receiver的重繪揣非,能獲得context
setNeedDisplay在receiver標(biāo)上一個(gè)需要被重新繪圖的標(biāo)記抡医,在下一個(gè)draw周期自動(dòng)重繪iPhone device的刷新頻率是60hz,也就是1/60秒后重繪
簡(jiǎn)單使用
先畫一條線
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext(); //獲取當(dāng)前繪制環(huán)境
CGContextSetLineWidth(ctx, 2); //設(shè)置線條寬度
CGContextSetStrokeColorWithColor(ctx, [[UIColor redColor] CGColor]);//設(shè)置線條顏色
CGContextBeginPath(ctx); //開始配置繪制路徑
CGContextMoveToPoint(ctx, 100, 100); //設(shè)置起點(diǎn)為(100,100)
CGContextAddLineToPoint(ctx, 200, 200); //添加一個(gè)直線到點(diǎn)(200,200)
CGContextDrawPath(ctx, kCGPathStroke); //繪制路徑
}
這里分為兩部分:
- 獲取當(dāng)前上下文并設(shè)置相關(guān)設(shè)置
UIGraphicsGetCurrentContext()
用來獲取當(dāng)前繪制環(huán)境早敬,只能在drawRect里面獲取該上下文忌傻。
這里設(shè)置了線條寬度為2,線條顏色為紅色搞监。 - 繪制路徑
繪制路徑要以CGContextBeginPath()
開始水孩。
直線、弧琐驴、曲線開始于當(dāng)前點(diǎn)俘种。空路徑?jīng)]有當(dāng)前點(diǎn),我們必須調(diào)用CGContextMoveToPoint
來設(shè)置第一個(gè)子路徑的起始點(diǎn)绝淡,或者調(diào)用一個(gè)便利函數(shù)來隱式地完成該任務(wù)宙刘。
最后使用CGContextStrokePath()
繪制,也可以使用CGContextDrawPath()
選擇繪制方法牢酵。
設(shè)置上下文的屬性
CGContextRef狀態(tài)
//保存CGContextRef當(dāng)前的繪圖狀態(tài)悬包,方便以后恢復(fù)該狀態(tài)。CGContextSaveGState()函數(shù)保存的繪圖狀態(tài)馍乙,不僅包括當(dāng)前坐標(biāo)系統(tǒng)的狀態(tài)布近,也包括當(dāng)前設(shè)置的填充風(fēng)格、線條風(fēng)格丝格、陰影風(fēng)格等各種繪圖狀態(tài)撑瞧。但 CGContextSaveGState()函數(shù)不會(huì)保存當(dāng)前繪制的圖形
void CGContextSaveGState(CGContextRef__nullable c)
//把CGContextRef的狀態(tài)恢復(fù)到最近一次保存時(shí)的狀態(tài)
void CGContextRestoreGState(CGContextRef__nullable c)
坐標(biāo)空間和變化
UIKit是iPhone SDK的Cocoa Touch層的核心framework,是iPhone應(yīng)用程序圖形界面和事件驅(qū)動(dòng)的基礎(chǔ)显蝌,它和傳統(tǒng)的windows桌面一樣预伺,坐標(biāo)系是y軸向下的; Core Graphics(Quartz)一個(gè)基于2D的圖形繪制引擎,它的坐標(biāo)系則是y軸向上的曼尊;而OpenGL ES是iPhone SDK的2D和3D繪制引擎扭屁,它使用左手坐標(biāo)系,它的坐標(biāo)系也是y軸向上的涩禀,如果不考慮z軸,在二維下它的坐標(biāo)系和Quartz是一樣的然眼。
//縮放坐標(biāo)系統(tǒng)
該方法控制坐標(biāo)系統(tǒng)水平方向上縮放 sx艾船,垂直方向上縮放 sy。在縮放后的坐標(biāo)系統(tǒng)上繪制圖形時(shí),所有點(diǎn)的 X 坐標(biāo)都相當(dāng)于乘以 sx 因子屿岂,所有點(diǎn)的 Y 坐標(biāo)都相當(dāng)于乘以 sy因子践宴。
void CGContextScaleCTM(CGContextRef__nullable c, CGFloat sx, CGFloat sy)
//平移坐標(biāo)系統(tǒng)
該方法相當(dāng)于把原來位于 (0, 0) 位置的坐標(biāo)原點(diǎn)平移到 (tx, ty)點(diǎn)。在平移后的坐標(biāo)系統(tǒng)上繪制圖形時(shí)爷怀,所有坐標(biāo)點(diǎn)的 X坐標(biāo)都相當(dāng)于增加了 tx阻肩,所有點(diǎn)的 Y坐標(biāo)都相當(dāng)于增加了 ty。
void CGContextTranslateCTM(CGContextRef__nullable c,
CGFloat tx, CGFloat ty)
//旋轉(zhuǎn)坐標(biāo)系統(tǒng)
該方法控制坐標(biāo)系統(tǒng)旋轉(zhuǎn) angle 弧度运授。在縮放后的坐標(biāo)系統(tǒng)上繪制圖形時(shí)烤惊,所有坐標(biāo)點(diǎn)的 X、Y坐標(biāo)都相當(dāng)于旋轉(zhuǎn)了 angle弧度之后的坐標(biāo)吁朦。
void CGContextRotateCTM(CGContextRef__nullable c, CGFloat angle)
//使用 transform變換矩陣對(duì) CGContextRef的坐標(biāo)系統(tǒng)執(zhí)行變換柒室,通過使用坐標(biāo)矩陣可以對(duì)坐標(biāo)系統(tǒng)執(zhí)行任意變換。
void CGContextConcatCTM(CGContextRef__nullable c,
CGAffineTransform transform)
//獲取CGContextRef的坐標(biāo)系統(tǒng)的變換矩陣
CGAffineTransform CGContextGetCTM(CGContextRef__nullable c)
繪圖屬性設(shè)置相關(guān)函數(shù)
//設(shè)置繪制直線逗宜、邊框時(shí)的線條寬度
void CGContextSetLineWidth(CGContextRef__nullable c, CGFloat width)
//設(shè)置線段端點(diǎn)的繪制形狀雄右。該屬性支持如下三個(gè)值。
typedef CF_ENUM(int32_t, CGLineCap) {
kCGLineCapButt, //沒有端點(diǎn)纺讲,線條結(jié)尾處直接結(jié)束擂仍,這是默認(rèn)值。
kCGLineCapRound,//圓形端點(diǎn)熬甚,線條結(jié)尾處繪制一個(gè)直徑為線條寬度的半圓逢渔。
kCGLineCapSquare//方形端點(diǎn)。線條結(jié)尾處繪制半個(gè)邊長(zhǎng)為線條寬度的正方形则涯。需要說明的是复局,這種形狀的端點(diǎn)與“butt”形狀的端點(diǎn)十分相似,只是采用這種形式的端點(diǎn)的線條略長(zhǎng)一點(diǎn)而已
};
void CGContextSetLineCap(CGContextRef__nullable c, CGLineCap cap)
typedef CF_ENUM(int32_t, CGLineJoin) {
kCGLineJoinMiter, // 這是默認(rèn)的屬性值粟判。該方格的連接點(diǎn)形狀如圖1所示亿昏。
kCGLineJoinRound, // 稍微圓角, 該方格的連接點(diǎn)形狀如圖2所示。
kCGLineJoinBevel // 斜角,該方格的連接點(diǎn)形狀如圖3所示档礁。
};
//設(shè)置線條連接點(diǎn)的風(fēng)格角钩,該屬性支持如上三個(gè)值:
void CGContextSetLineJoin(CGContextRef__nullable c, CGLineJoin join)
//當(dāng)把連接點(diǎn)風(fēng)格設(shè)為meter風(fēng)格時(shí),該方法用于控制銳角箭頭的長(zhǎng)度*/
void CGContextSetMiterLimit(CGContextRef__nullable c, CGFloat limit)
圖1 | 圖2 | 圖3 |
---|---|---|
/*
Linedash pattern(虛線模式)允許我們沿著描邊繪制虛線呻澜。我們通過在CGContextSetLineDash結(jié)構(gòu)體中指定虛線數(shù)組和虛線相位來控制虛線的大小及位置递礼。
其中l(wèi)engths屬性指定了虛線段的長(zhǎng)度,該值是在繪制片斷與未繪制片斷之間交替(實(shí)線羹幸、空白脊髓、實(shí)線、空白栅受、實(shí)線....)将硝。phase屬性指定虛線模式的起始點(diǎn)恭朗,phase實(shí)際是虛線中實(shí)線長(zhǎng)度的余數(shù),當(dāng)phase<length時(shí)向左偏移phase%length依疼,phase>length向右偏移phase%length痰腮,phase或phase%length為0時(shí)不偏移。
*/
void CGContextSetLineDash(CGContextRef__nullable c, CGFloat phase,const CGFloat *__nullable lengths, size_t count)
注意:CGContextSetLineDash的使用需要在存在路徑的基礎(chǔ)上律罢。
其他設(shè)置
//設(shè)置彎曲的路徑中的圖形上下文的準(zhǔn)確性膀值。
void CGContextSetFlatness(CGContextRef__nullable c, CGFloat flatness)
//設(shè)置全局透明度
void CGContextSetAlpha(CGContextRef__nullable c, CGFloat alpha)
//設(shè)置CGContextRef的疊加模式。Quartz 2D支持多種疊加模
void CGContextSetBlendMode(CGContextRef __nullable c, CGBlendMode mode)
繪制路徑
繪制路徑要以CGContextBeginPath()
開始误辑。
//開始創(chuàng)建路徑.
void CGContextBeginPath(CGContextRef__nullable c)
//開始一個(gè)新的子路徑點(diǎn)
void CGContextMoveToPoint(CGContextRef__nullable c,
CGFloat x, CGFloat y)
//添加一條直線段從當(dāng)前指向的(x,y)
void CGContextAddLineToPoint(CGContextRef__nullable c,
CGFloat x, CGFloat y)
/**
* 從當(dāng)前添加一個(gè)三次Bezier曲線
* @param cp1x 控制點(diǎn)1 x坐標(biāo)
* @param cp1y 控制點(diǎn)1 y坐標(biāo)
* @param cp2x 控制點(diǎn)2 x坐標(biāo)
* @param cp2y 控制點(diǎn)2 y坐標(biāo)
* @param x 直線的終點(diǎn) x坐標(biāo)
* @param y 直線的終點(diǎn) y坐標(biāo)
*/
void CGContextAddCurveToPoint(CGContextRef__nullable c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y)
/**
* 從當(dāng)前添加一個(gè)二次Bezier曲線
* @param cpx 控制點(diǎn) x坐標(biāo)
* @param cpy 控制點(diǎn) y坐標(biāo)
* @param x 直線的終點(diǎn) x坐標(biāo)
* @param y 直線的終點(diǎn) y坐標(biāo)
*/
void CGContextAddQuadCurveToPoint(CGContextRef__nullable c, CGFloat cpx, CGFloat cpy,CGFloat x,CGFloat y)
//關(guān)閉當(dāng)前上下文的子路徑,且當(dāng)前點(diǎn)和起點(diǎn)連接起來(需要在繪制之前調(diào)用)
void CGContextClosePath(CGContextRef__nullable c)
//添加一個(gè)矩形路徑
void CGContextAddRect(CGContextRef__nullable c, CGRect rect)
//添加多個(gè)矩形路徑
void CGContextAddRects(CGContextRef__nullable c,
const CGRect * __nullable rects, size_t count)
//添加多條直線路徑
void CGContextAddLines(CGContextRef__nullable c,
const CGPoint * __nullable points, size_t count)
//根據(jù)一個(gè)矩形,繪制橢圓(圓形)
void CGContextAddEllipseInRect(CGContextRef__nullable c, CGRect rect)
/**
* 添加弧形路徑
* @param x 中心點(diǎn)x坐標(biāo)
* @param y 中心點(diǎn)y坐標(biāo)
* @param radius 半徑
* @param startAngle 起始弧度
* @param endAngle 終止弧度
* @param clockwise 是否逆時(shí)針繪制沧踏,1逆時(shí)針,0順時(shí)針
*/
void CGContextAddArc(CGContextRef__nullable c, CGFloat x,CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle,int clockwise)
//這個(gè)函數(shù)使用一個(gè)序列的三次貝塞爾曲線創(chuàng)建一個(gè)弧 原理:首先畫兩條線稀余,這兩條線分別是 current point to (x1,y1)和(x1,y1) to (x2,y2).這樣就是出現(xiàn)一個(gè)以(x1,y1)為頂點(diǎn)的兩條射線悦冀,然后定義半徑長(zhǎng)度,這個(gè)半徑是垂直于兩條射線的睛琳,這樣就能決定一個(gè)圓了盒蟆,如果當(dāng)前點(diǎn)和第一個(gè)切點(diǎn)的弧(起點(diǎn))是不平等的,那么會(huì)添加一條直線段從當(dāng)前指向第一個(gè)切點(diǎn)∈ζ弧的終點(diǎn)成為新的當(dāng)前點(diǎn)的路徑
void CGContextAddArcToPoin(CGContextRef __nullable c, CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat radius)
//添加路徑到圖形上下文
void CGContextAddPath(CGContextRef__nullable c, CGPathRef__nullable path)
繪制路徑
//使用繪制當(dāng)前路徑時(shí)覆蓋的區(qū)域作為當(dāng)前CGContextRef中的新路徑历等,一般配合CGContextClip使用
void CGContextReplacePathWithStrokedPath(CGContextRef__nullable c)
//當(dāng)前路徑是否包含任何的子路徑
(Bool)CGContextIsPathEmpty(CGContextRef__nullable c)
//返回一個(gè)非空的路徑中的當(dāng)前點(diǎn)
(CGPoint)CGContextGetPathCurrentPoint(CGContextRef__nullable c)
//返回包含當(dāng)前路徑的最小矩形
(CGRect)CGContextGetPathBoundingBox(CGContextRef__nullable c)
//返回當(dāng)前上下文的路徑的副本
(CGPathRef __nullable)CGContextCopyPath(CGContextRef__nullable c)
//檢查當(dāng)前路徑中是否包含指定的點(diǎn)
(Bool)CGContextPathContainsPoint(CGContextRef__nullable c,
CGPoint point, CGPathDrawingMode mode)
繪制方式
typedef CF_ENUM (int32_t, CGPathDrawingMode) {
kCGPathFill, //填充
kCGPathEOFill, //奇偶填充(奇填偶不填)
kCGPathStroke, //描邊
kCGPathFillStroke, //描邊并填充
kCGPathEOFillStroke //奇偶填充并描邊
};
kCGPathFill | kCGPathEOFill | kCGPathStroke | kCGPathFillStroke | kCGPathEOFillStroke |
---|---|---|---|---|
//使用指定模式繪制當(dāng)前CGContextRef中所包含的路徑。
void CGContextDrawPath(CGContextRef__nullable c, CGPathDrawingMode mode)
//填充該路徑包圍的區(qū)域
void CGContextFillPath(CGContextRef__nullable c)
//使用奇偶規(guī)則來填充該路徑包圍的區(qū)域辟癌。奇偶規(guī)則指某個(gè)點(diǎn)被路徑包圍了奇數(shù)次則繪制該點(diǎn)寒屯,否則不繪制
void CGContextEOFillPath(CGContextRef__nullable c)
//使用當(dāng)前 CGContextRef設(shè)置的線寬繪制路徑
void CGContextStrokePath(CGContextRef__nullable c)
//填充rect代表的矩形
void CGContextFillRect(CGContextRef__nullable c, CGRect rect)
//填充多個(gè)矩形
void CGContextFillRects(CGContextRef__nullable c,
const CGRect * __nullable rects, size_t count)
//使用當(dāng)前 CGContextRef設(shè)置的線寬繪制矩形框
void CGContextStrokeRect(CGContextRef__nullable c, CGRect rect)
//使用指定線寬繪制矩形框
void CGContextStrokeRectWithWidth(CGContextRef__nullable c,
CGRect rect, CGFloat width)
//清除指定矩形區(qū)域上繪制的圖形
void CGContextClearRect(CGContextRef__nullable c, CGRect rect)
//填充rect矩形的內(nèi)切橢圓區(qū)域
void CGContextFillEllipseInRect(CGContextRef__nullable c,
CGRect rect)
//使用當(dāng)前 CGContextRef設(shè)置的線寬繪制rect矩形的內(nèi)切橢圓
void CGContextStrokeEllipseInRect(CGContextRef__nullable c, CGRect rect)
/**
* 使用當(dāng)前 CGContextRef 設(shè)置的線寬繪制多條線段
* @param c 當(dāng)前上下文
* @param points 線段數(shù)組(必須成對(duì)出現(xiàn),起點(diǎn)終點(diǎn)配對(duì))
* @param count 數(shù)組長(zhǎng)度
*/
void CGContextStrokeLineSegments(CGContextRef__nullable c,
const CGPoint * __nullable points, size_t count)
//修改當(dāng)前剪貼路徑黍少,使用非零繞數(shù)規(guī)則
void CGContextClip(CGContextRef__nullable c)
//修改當(dāng)前剪貼路徑寡夹,使用奇偶規(guī)則
void CGContextEOClip(CGContextRef__nullable c)
//剪切遮罩處理(針對(duì)圖片)
void CGContextClipToMask(CGContextRef__nullable c, CGRect rect, CGImageRef__nullable mask)
//獲取到了需要繪制的圖形上下文的位置與大小
CGRect CGContextGetClipBoundingBox(CGContextRef__nullable c)
//剪切指定矩形區(qū)域外的部分
void CGContextClipToRect(CGContextRef__nullable c, CGRect rect)
//剪切指定多個(gè)矩形區(qū)域外的部分
void CGContextClipToRects(CGContextRef__nullable c,const CGRect * rects, size_t count)
設(shè)置顏色
// 設(shè)置描邊和填充色為紅色
[[UIColor redColor] set]
// 設(shè)置填充色為綠色
[[UIColor greenColor] setFill]
// 設(shè)置描邊色為黃色
[[UIColor yellowColor] set]
//使用指定顏色來設(shè)置該CGContextRef的填充顏色
void CGContextSetFillColorWithColor(CGContextRef__nullable c,
CGColorRef __nullable color)
//使用指定顏色來設(shè)置該CGContextRef的線條顏色
void CGContextSetStrokeColorWithColor(CGContextRef__nullable c,
CGColorRef __nullable color)
//顏色空間填充
void CGContextSetFillColorSpace(CGContextRef__nullable c, CGColorSpaceRef__nullable space)
//設(shè)置線框顏色空間
void CGContextSetStrokeColorSpace(CGContextRef__nullable c,
CGColorSpaceRef __nullable space)
//設(shè)置填充顏色空間 CGFloat redColor[4] = {1.0,0,0,1.0};
void CGContextSetFillColor(CGContextRef__nullable c,const CGFloat *__nullable components(redColor))
//設(shè)置畫筆顏色 CGFloat redColor[4] = {1.0,0,0,1.0};
void CGContextSetStrokeColor(CGContextRef__nullable c,const CGFloat *__nullable components(redColor))
//設(shè)置該CGContextRef使用位圖填充
void CGContextSetFillPattern(CGContextRef__nullable c, CGPatternRef__nullable pattern,const CGFloat * __nullable components)
//設(shè)置該CGContextRef使用位圖繪制線條、邊框
void CGContextSetStrokePattern(CGContextRef__nullable c, CGPatternRef__nullable pattern,const CGFloat * __nullable components)
//設(shè)置該CGContextRef采用位圖填充的相位
void CGContextSetPatternPhase(CGContextRef__nullable c, CGSize phase)
//使用灰色來設(shè)置該CGContextRef的填充顏色
void CGContextSetGrayFillColor(CGContextRef__nullable c,
CGFloat gray, CGFloat alpha)
//使用灰色來設(shè)置該CGContextRef的線條顏色
void CGContextSetGrayStrokeColor(CGContextRef__nullable c,
CGFloat gray, CGFloat alpha)
//使用RGB顏色模式來設(shè)置該CGContextRef的填充顏色
void CGContextSetRGBFillColor(CGContextRef__nullable c, CGFloat red,
CGFloat green, CGFloat blue, CGFloat alpha)
//設(shè)置畫筆顏色
void CGContextSetRGBStrokeColor(CGContextRef__nullable c,
CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
//使用CMYK顏色模式來設(shè)置該CGContextRef的填充顏色
void CGContextSetCMYKFillColor(CGContextRef__nullable c,
CGFloat cyan, CGFloat magenta, CGFloat yellow, CGFloat black, CGFloat alpha)
//使用CMYK顏色模式來設(shè)置該CGContextRef的線條顏色
void CGContextSetCMYKStrokeColor(CGContextRef__nullable c,
CGFloat cyan, CGFloat magenta, CGFloat yellow, CGFloat black, CGFloat alpha)
//在當(dāng)前圖形狀態(tài)設(shè)置渲染意向
void CGContextSetRenderingIntent(CGContextRef__nullable c,
CGColorRenderingIntent intent)
圖片
UIKit是坐標(biāo)系是y軸向下的; Core Graphics(Quartz)一個(gè)基于2D的圖形繪制引擎厂置,它的坐標(biāo)系則是y軸向上的菩掏;而OpenGL ES是iPhone SDK的2D和3D繪制引擎,它使用左手坐標(biāo)系昵济,它的坐標(biāo)系也是y軸向上的智绸,如果不考慮z軸,在二維下它的坐標(biāo)系和Quartz是一樣的访忿。
所以圖像繪制后會(huì)倒立過來瞧栗,我們可以修改坐標(biāo)系來處理;或者使用UIImage的drawInRect函數(shù)海铆,該函數(shù)內(nèi)部能自動(dòng)處理圖片的正確方向迹恐。
//繪制圖像到圖形上下文中
void CGContextDrawImage(CGContextRef__nullable c, CGRect rect,
CGImageRef __nullable image)
//重復(fù)繪制的圖像,擴(kuò)展到提供的矩形卧斟,填補(bǔ)當(dāng)前剪輯區(qū)域
void CGContextDrawTiledImage(CGContextRef__nullable c, CGRect rect,
CGImageRef __nullable image)
//獲取當(dāng)前CGContextRef在放大圖片時(shí)的插值質(zhì)量
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef__nullable c)
//設(shè)置圖形上下文的插值質(zhì)量水平
void CGContextSetInterpolationQuality(CGContextRef__nullable c,
CGInterpolationQuality quality)
注意:因?yàn)閁IKit和CG坐標(biāo)系y軸相反殴边,所以圖片繪制將會(huì)上下顛倒通熄。
1.可以通過修改當(dāng)前坐標(biāo)系來恢復(fù)。
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
2.使用UIImage的drawInRect函數(shù)找都,該函數(shù)內(nèi)部能自動(dòng)處理圖片的正確方向
UIGraphicsPushContext(context);
[image drawInRect:CGRectMake(0, 0, width, height)];
UIGraphicsPopContext();
陰影
//設(shè)置陰影在X、Y方向上的偏移廊酣,以及模糊度和陰影的顏色
void CGContextSetShadowWithColor(CGContextRef__nullable c,
CGSize offset, CGFloat blur, CGColorRef __nullable color)
//設(shè)置陰影在X能耻、Y方向上的偏移,以及模糊度(blur值越大亡驰,陰影越模糊)晓猛。該函數(shù)沒有設(shè)置陰影顏色,默認(rèn)使用1/3透明的黑色(即RGBA{0, 0, 0, 1.0/3.0})作為陰影顏色
void CGContextSetShadow(CGContextRef__nullable c, CGSize offset,
CGFloat blur)
漸變
//繪制一個(gè)漸變填充定義的出發(fā)點(diǎn)和落腳點(diǎn)沿線變化
void CGContextDrawLinearGradient(CGContextRef__nullable c,
CGGradientRef __nullable gradient, CGPoint startPoint, CGPoint endPoint,
CGGradientDrawingOptions options)
//繪制一個(gè)沿著由所提供的開始和結(jié)束的圓限定的區(qū)域變化的漸變填充
void CGContextDrawRadialGradient(CGContextRef__nullable c,
CGGradientRef __nullable gradient, CGPoint startCenter, CGFloat startRadius,
CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options)
//使用指定的陰影的背景凡辱,填充剪切路徑
void CGContextDrawShading(CGContextRef __nullable c,
__nullable CGShadingRef shading)
//示例
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSArray *colors = @[(__bridge id)UIColor.redColor.CGColor,
(__bridge id)UIColor.yellowColor.CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef)colors, NULL);
CGPoint startPoint = CGPointMake(0, rect.size.height / 2);
CGPoint endPoint = CGPointMake(rect.size.width, startPoint.y);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
文本
//設(shè)置當(dāng)前字符間距
void CGContextSetCharacterSpacing(CGContextRef__nullable c,
CGFloat spacing)
//設(shè)置要繪制文本的位置
void CGContextSetTextPosition(CGContextRef__nullable c,
CGFloat x, CGFloat y)
//返回在繪制文本的位置
CGPoint CGContextGetTextPosition(CGContextRef __nullable c)
//設(shè)置當(dāng)前文本矩陣
void CGContextSetTextMatrix(CGContextRef__nullable c,
CGAffineTransform t)
//返回當(dāng)前文本矩陣
CGAffineTransform CGContextGetTextMatrix(CGContextRef__nullable c)
//設(shè)置當(dāng)前文本的繪圖模式
void CGContextSetTextDrawingMode(CGContextRef__nullable c,
CGTextDrawingMode mode)
//設(shè)置上下文的字體
void CGContextSetFont(CGContextRef__nullable c,
CGFontRef __nullable font)
//設(shè)置上下文的字體大小
void CGContextSetFontSize(CGContextRef__nullable c, CGFloat size)
//在所提供的位置繪制字形
void CGContextShowGlyphsAtPositions(CGContextRef__nullable c,
const CGGlyph * __nullable glyphs, const CGPoint * __nullable Lpositions,
size_t count)
//繪制一個(gè)PDF頁(yè)面到當(dāng)前的用戶空間
void CGContextDrawPDFPage(CGContextRef__nullable c,
CGPDFPageRef __nullable page)
輸出頁(yè)面
//基于頁(yè)面的圖形上下文中開始了新的一頁(yè)
void CGContextBeginPage(CGContextRef__nullable c,const CGRect *__nullable mediaBox)
//在基于頁(yè)面的圖形上下文結(jié)束當(dāng)前的頁(yè)面
void CGContextEndPage(CGContextRef__nullable c)
上下文相關(guān)方法
//圖形上下文的引用計(jì)數(shù)+1
(CGContextRef __nullable)CGContextRetain(CGContextRef__nullable c)
//圖形上下文的引用計(jì)數(shù)-1
void CGContextRelease(CGContextRef__nullable c)
//強(qiáng)制所有掛起的繪圖操作在一個(gè)窗口上下文中立即被渲染到目標(biāo)設(shè)備
void CGContextFlush(CGContextRef__nullable c)
//將一個(gè)窗口的圖像上下文內(nèi)容更新戒职,即所有的繪圖操作都會(huì)在下次同步到窗口上
void CGContextSynchronize(CGContextRef__nullable c)
抗鋸齒
//設(shè)置該CGContextRef是否應(yīng)該抗鋸齒(即光滑圖形曲線邊緣,讓字體渲染比較清晰 提高畫質(zhì)以使之柔和 )
void CGContextSetShouldAntialias(CGContextRef__nullable c,
bool shouldAntialias)
//設(shè)置該CGContextRef是否允許抗鋸齒
void CGContextSetAllowsAntialiasing(CGContextRef__nullable c,
bool allowsAntialiasing)
字體展示
//設(shè)置該CGContextRef是否允許光滑字體
void CGContextSetShouldSmoothFonts(CGContextRef__nullable c,
bool shouldSmoothFonts)
//設(shè)置該CGContextRef是否允許光滑字體
void CGContextSetAllowsFontSmoothing(CGContextRef__nullable c,
bool allowsFontSmoothing)
//啟用或禁用圖形上下文中的子像素定位透乾。
void CGContextSetShouldSubpixelPositionFonts(
CGContextRef __nullable c, bool shouldSubpixelPositionFonts)
//設(shè)置是否允許圖形上下文的子像素定位
void CGContextSetAllowsFontSubpixelPositioning(
CGContextRef __nullable c, bool allowsFontSubpixelPositioning)
//在圖形上下文中啟用或禁用子像素量化洪燥。
void CGContextSetShouldSubpixelQuantizeFonts(
CGContextRef __nullable c, bool shouldSubpixelQuantizeFonts)
//設(shè)置是否允許圖形上下文的子像素量化
void CGContextSetAllowsFontSubpixelQuantization(
CGContextRef __nullable c, bool allowsFontSubpixelQuantization)
透明層
/* 開始一個(gè)透明層。
直到相應(yīng)的調(diào)用CGContextEndTransparencyLayer乳乌,在指定范圍內(nèi)的所有后續(xù)繪制操作組合到一個(gè)完全透明的背景(它被視為一個(gè)單獨(dú)的目標(biāo)緩沖區(qū)從上下文)捧韵。
在透明層中繪制需要三步:
1. 調(diào)用函數(shù) CGContextBeginTransparencyLayer
2. 在透明層中繪制需要組合的對(duì)象
3. 調(diào)用函數(shù) CGContextEndTransparencyLayer*/
void CGContextBeginTransparencyLayer(CGContextRef__nullable c,
CFDictionaryRef __nullable auxiliaryInfo)
//開始透明度層,它的邊界是指定的矩形汉操,其內(nèi)容是有界的
void CGContextBeginTransparencyLayerWithRect(
CGContextRef __nullable c, CGRect rect, CFDictionaryRef__nullable auxInfo)
//結(jié)束一個(gè)透明層
void CGContextEndTransparencyLayer(CGContextRef__nullable c)
用戶空間對(duì)設(shè)備空間的變化
/* 獲取Quartz轉(zhuǎn)換用戶空間和設(shè)備空間的仿射變換 */
CGAffineTransform CGContextGetUserSpaceToDeviceSpaceTransform(CGContextRef__nullable c)
/*———— 點(diǎn) ————*/
/* 將一個(gè)CGPoint數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(DeviceSpace). */
CGPoint CGContextConvertPointToDeviceSpace(CGContextRef__nullable c,
CGPoint point)
/* 將一個(gè)CGPoint數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(UserSpace). */
CGPoint CGContextConvertPointToUserSpace(CGContextRef__nullable c,
CGPoint point)
/*———— 大小 ————*/
/* 將一個(gè)CGSize數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(DeviceSpace). */
CGSize CGContextConvertSizeToDeviceSpace(CGContextRef__nullable c, CGSize size)
/* 將一個(gè)CGSize數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(UserSpace). */
CGSize CGContextConvertSizeToUserSpace(CGContextRef__nullable c, CGSize size)
/*———— 矩形 ————*/
/* 將一個(gè)CGPoint數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(DeviceSpace)再来。 */
CGRect CGContextConvertRectToDeviceSpace(CGContextRef__nullable c,
CGRect rect)
/* 將一個(gè)CGPoint數(shù)據(jù)結(jié)構(gòu)從一個(gè)空間變換到另一個(gè)空間(UserSpace)。 */
CGRect CGContextConvertRectToUserSpace(CGContextRef__nullable c,
CGRect rect)