今天做頁(yè)面需要用到繪圖繪制虛線,由于平時(shí)不怎么用到繪圖,對(duì)繪圖的基礎(chǔ)也不是很好,所以寫(xiě)一篇關(guān)于繪圖的文章,鞏固下基礎(chǔ),并做下記錄
Quartz 2D繪圖的核心API是CGContextRef,該API并不是一個(gè)對(duì)象。由于Quartz 2D本身并不是面向?qū)ο蟮?,它是面向過(guò)程的API,Quartz 2D提供了大量函數(shù)來(lái)完成繪圖。
繪制圖形要重寫(xiě)drawRect方法,drawRect方法會(huì)在setNeedsDisplay方法掉用后,程序會(huì)自動(dòng)調(diào)用進(jìn)行重繪.drawRect方法一般情況下只會(huì)被調(diào)用一次. 當(dāng)某些情況下想要手動(dòng)重畫(huà)這個(gè)View,只需要調(diào)用[self setNeedsDisplay]方法即可.
在UIView中,重寫(xiě)drawRect: (CGRect) aRect方法,可以自己定義想要畫(huà)的圖案.
如果只需要繪制一次,重寫(xiě)自定義View即可,如果要多次進(jìn)行繪制,需要調(diào)用setNeedsDisplay,并根據(jù)參數(shù)進(jìn)行修改.
下面是要注意的一些細(xì)節(jié)
如果在UIView初始化時(shí)沒(méi)有設(shè)置rect大小,會(huì)導(dǎo)致drawRect不被調(diào)用.
該方法在調(diào)用sizeThatFits后被調(diào)用,所以可以先調(diào)用sizeToFit計(jì)算出size。然后系統(tǒng)自動(dòng)調(diào)用drawRect:方法.
通過(guò)設(shè)置contentMode屬性值為UIViewContentModeRedraw。那么將在每次設(shè)置或更改frame的時(shí)候自動(dòng)調(diào)用drawRect:
直接調(diào)用setNeedsDisplay,或者setNeedsDisplayInRect:觸發(fā)drawRect:,但是有個(gè)前提條件是rect不能為0.
繪制虛線
- (void)drawRect:(CGRect)rect {
// Drawing code.
//獲得處理的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置線條樣式
CGContextSetLineCap(context, kCGLineCapSquare);
//設(shè)置線段端點(diǎn)的繪制形狀.該屬性支持如下三個(gè)值.
//kCGLineCapButt:該屬性值指定不繪制端點(diǎn),線條結(jié)尾處直接結(jié)束.這是默認(rèn)值.
//kCGLineCapRound:該屬性值指定繪制圓形端點(diǎn),線條結(jié)尾處繪制一個(gè)直徑為線條寬度的半圓.
//kCGLineCapSquare:該屬性值指定繪制方形端點(diǎn).線條結(jié)尾處繪制半個(gè)邊長(zhǎng)為線條寬度的正方形.需要說(shuō)明的是,這種形狀的端點(diǎn)與“butt”形狀的端點(diǎn)十分相似
//設(shè)置線條粗細(xì)寬度
CGContextSetLineWidth(context, 2.0);
//設(shè)置顏色,顏色為0-1之間
CGContextSetRGBStrokeColor(context, 0.90, 0.90, 0.90, 1.0);
// CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
//開(kāi)始一個(gè)起始路徑
CGContextBeginPath(context);
//起始點(diǎn)設(shè)置為(0,0):注意這是上下文對(duì)應(yīng)區(qū)域中的相對(duì)坐標(biāo)
CGContextMoveToPoint(context, 0, 0);
//設(shè)置下一個(gè)坐標(biāo)點(diǎn)
CGContextAddLineToPoint(context, 100, 0);
//設(shè)置下一個(gè)坐標(biāo)點(diǎn)
CGContextAddLineToPoint(context, 100, 100);
//設(shè)置下一個(gè)坐標(biāo)點(diǎn)
CGContextAddLineToPoint(context, 0, 100);
CGContextAddLineToPoint(context, 0, 0);
//連接上面定義的坐標(biāo)點(diǎn)
// CGContextStrokePath(context);
CGFloat arr[] = {8,1};
//下面最后一個(gè)參數(shù)“2”代表排列的個(gè)數(shù)。
CGContextSetLineDash(context, 0, arr, 2);
CGContextDrawPath(context, kCGPathStroke);
} ```
######CGContextRef的繪圖相關(guān)函數(shù)
* `void CGContextClearRect(CGContextRef c, CGRect rect);
擦除指定矩形區(qū)域上繪制的圖形`
* `void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode);使用指定模式繪制當(dāng)前CGContextRef中所包
含的路徑。第二個(gè)參數(shù)支持 kCGPathFill、kCGPathEOFill、kCGPathStroke、kCGPathFillStroke、kCGPathEOFillStroke等枚舉值`
* `void CGContextEOFillPath(CGContextRef c);
使用奇偶規(guī)則來(lái)填充該路徑包圍的區(qū)域。奇偶規(guī)則指:如果某個(gè)點(diǎn)被路徑包圍了奇數(shù)次,系統(tǒng)繪制該點(diǎn);如果被路徑包圍了偶數(shù)次,系統(tǒng)不繪制該點(diǎn)`
* `void CGContextFillPath(CGContextRef c);
填充該路徑包圍的區(qū)域`
* `void CGContextFillRect(CGContextRef c,CGRect rect);
填充rect代表的矩形`
* `void CGContextFillRects(CGContextRef c,const CGRect rects[], size_t count);
填充多個(gè)矩形`
* `void CGContextFillEllipseInRect(CGContextRef context, CGRect rect);
填充rect矩形的內(nèi)切橢圓區(qū)域`
* `void CGContextStrokePath(CGContextRef c);
使用當(dāng)前 CGContextRef設(shè)置的線寬繪制路徑`
* `void CGContextStrokeRect(CGContextRef c, CGRect rect);
使用當(dāng)前 CGContextRef設(shè)置的線寬繪制矩形框
void CGContextStrokeRectWithWidth(CGContextRef c,`
* `CGRect rect, CGFloat width);
使用指定線寬繪制矩形框`
* `void CGContextReplacePathWithStrokedPath(CGContextRef c);
使用繪制當(dāng)前路徑時(shí)覆蓋的區(qū)域作為當(dāng)前CGContextRef
中的新路徑。舉例來(lái)說(shuō),假如當(dāng)前CGContextRef包含一個(gè)圓形路徑且線寬為10,調(diào)用該方法后,當(dāng)前CGContextRef將包含一個(gè)環(huán)寬為10的環(huán)形路徑`
* `void CGContextStrokeEllipseInRect(CGContextRef context,CGRect rect);
使用當(dāng)前 CGContextRef設(shè)置的線寬繪制rect矩形的內(nèi)切橢圓`
* `void CGContextStrokeLineSegments(CGContextRef c,
const CGPoint points[], size_t count);
使用當(dāng)前 CGContextRef設(shè)置的線寬繪制多條線段。該
方法需要傳入2N個(gè)CGPoint組成的數(shù)組,其中1、2個(gè)點(diǎn)
組成第一條線段,3、4個(gè)點(diǎn)組成第2條線段,以此類(lèi)推`
######設(shè)置繪圖屬性的相關(guān)函數(shù)
* `void CGContextSaveGState(CGContextRef c);
保存CGContextRef當(dāng)前的繪圖狀態(tài),方便以后恢復(fù)該狀態(tài)`
* `void CGContextRestoreGState(CGContextRef c);
把CGContextRef的狀態(tài)恢復(fù)到最近一次保存時(shí)的狀態(tài)`
* `CGInterpolationQuality CGContextGetInterpolation
Quality(CGContextRef c);
獲取當(dāng)前CGContextRef在放大圖片時(shí)的插值質(zhì)量`
* `void CGContextSetInterpolationQuality(CGContextRef c,
CGInterpolationQuality quality);
設(shè)置當(dāng)前CGContextRef在放大圖片時(shí)的插值質(zhì)量`
* `void CGContextSetLineCap(CGContextRef c, CGLineCap cap);
設(shè)置線段端點(diǎn)的繪制形狀。該屬性支持如下三個(gè)值。`
* `kCGLineCapButt:該屬性值指定不繪制端點(diǎn),
線條結(jié)尾處直接結(jié)束。這是默認(rèn)值。`
* `kCGLineCapRound:該屬性值指定繪制圓形端點(diǎn),
線條結(jié)尾處繪制一個(gè)直徑為線條寬度的半圓。`
* `kCGLineCapSquare:該屬性值指定繪制方形端點(diǎn)。
線條結(jié)尾處繪制半個(gè)邊長(zhǎng)為線條寬度的正方形。需要
說(shuō)明的是,這種形狀的端點(diǎn)與“butt”形狀的端點(diǎn)十分相似,只是采用這種形式的端點(diǎn)的線條略長(zhǎng)一點(diǎn)而已`
* `void CGContextSetLineDash(CGContextRef c,
CGFloat phase, const CGFloat lengths[],size_t count);
設(shè)置繪制邊框時(shí)所用的點(diǎn)線模式,Quartz 2D支持非常強(qiáng)大的點(diǎn)線模式.`
* `void CGContextSetLineJoin(CGContextRef c, CGLineJoin join);
設(shè)置線條連接點(diǎn)的風(fēng)格`
* `void CGContextSetLineWidth(CGContextRef c, CGFloat width);
設(shè)置繪制直線、邊框時(shí)的線條寬度`
* `void CGContextSetMiterLimit(CGContextRef c, CGFloat limit);
當(dāng)把連接點(diǎn)風(fēng)格設(shè)為meter風(fēng)格時(shí),該方法用于控制銳角箭頭的長(zhǎng)度`
* `void CGContextSetPatternPhase(CGContextRef c, CGSize phase);
設(shè)置該CGContextRef采用位圖填充的相位`
* `void CGContextSetFillPattern(CGContextRef c,
CGPatternRef pattern,const CGFloat components[]);
設(shè)置該CGContextRef使用位圖填充`
* `void CGContextSetShouldAntialias(CGContextRef c, bool shouldAntialias);
設(shè)置該CGContextRef是否應(yīng)該抗鋸齒(即光滑圖形曲線邊緣)`
* `void CGContextSetStrokePattern(CGContextRef c,
CGPatternRef pattern, const CGFloat components[]);
設(shè)置該CGContextRef使用位圖繪制線條、邊框
續(xù)表`
* `void CGContextSetBlendMode(CGContextRef context,CGBlendMode mode);
設(shè)置CGContextRef的疊加模式。Quartz 2D
支持多種疊加模式`
* `void CGContextSetAllowsAntialiasing(CGContextRef context, bool allowsAntialiasing);
設(shè)置該CGContextRef是否允許抗鋸齒`
* `void CGContextSetAllowsFontSmoothing(CGContextRef context, bool allowsFontSmoothing);
設(shè)置該CGContextRef是否允許光滑字體`
* `void CGContextSetShouldSmoothFonts(CGContextRef c,bool shouldSmoothFonts);
設(shè)置該CGContextRef是否允許光滑字體`
* `void CGContextSetAlpha (CGContextRef c, CGFloat alpha);
設(shè)置全局透明度`
* `void CGContextSetCMYKFillColor(CGContextRef c,
CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha);
使用CMYK顏色模式來(lái)設(shè)置該CGContextRef的填充顏色`
* `void CGContextSetCMYKStrokeColor(CGContextRef c,
CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha);
使用CMYK顏色模式來(lái)設(shè)置該CGContextRef的線條顏色`
* `void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color);
使用指定顏色來(lái)設(shè)置該CGContextRef的填充顏色`
* `void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color);
使用指定顏色來(lái)設(shè)置該CGContextRef的線條顏色`
* `void CGContextSetGrayFillColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用灰色來(lái)設(shè)置該CGContextRef的填充顏色`
* `void CGContextSetGrayStrokeColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用灰色來(lái)設(shè)置該CGContextRef的線條顏色`
* `void CGContextSetRGBFillColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用RGB顏色模式來(lái)設(shè)置該CGContextRef的填充顏色`
* `void CGContextSetRGBStokeColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用RGB顏色模式來(lái)設(shè)置該CGContextRef的線條顏色`
* `void CGContextSetShadow(CGContextRef context,
CGSize offset, CGFloat blur);
設(shè)置陰影在X、Y方向上的偏移,以及模糊度(blur值越大,陰影越模糊)。該函數(shù)沒(méi)有設(shè)置陰影顏色,默認(rèn)使用1/3透明的黑色(即RGBA{0, 0, 0, 1.0/3.0})作為陰影顏色`
* `void CGContextSetShadowWithColor(CGContextRef context,
CGSize offset, CGFloat blur, CGColorRef color);
設(shè)置陰影在X、Y方向上的偏移,以及模糊度和陰影的顏色`