今天做页面需要用到绘图绘制虚线,由于平时不怎么用到绘图,对绘图的基础也不是很好,所以写一篇关于绘图的文章,巩固下基础,并做下记录
Quartz 2D绘图的核心API是CGContextRef,该API并不是一个对象。由于Quartz 2D本身并不是面向对象的,它是面向过程的API,Quartz 2D提供了大量函数来完成绘图。
绘制图形要重写drawRect方法,drawRect方法会在setNeedsDisplay方法掉用后,程序会自动调用进行重绘.drawRect方法一般情况下只会被调用一次. 当某些情况下想要手动重画这个View,只需要调用[self setNeedsDisplay]方法即可.
在UIView中,重写drawRect: (CGRect) aRect方法,可以自己定义想要画的图案.
如果只需要绘制一次,重写自定义View即可,如果要多次进行绘制,需要调用setNeedsDisplay,并根据参数进行修改.
下面是要注意的一些细节
如果在UIView初始化时没有设置rect大小,会导致drawRect不被调用.
该方法在调用sizeThatFits后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法.
通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:
直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0.
绘制虚线
- (void)drawRect:(CGRect)rect {
// Drawing code.
//获得处理的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//设置线条样式
CGContextSetLineCap(context, kCGLineCapSquare);
//设置线段端点的绘制形状.该属性支持如下三个值.
//kCGLineCapButt:该属性值指定不绘制端点,线条结尾处直接结束.这是默认值.
//kCGLineCapRound:该属性值指定绘制圆形端点,线条结尾处绘制一个直径为线条宽度的半圆.
//kCGLineCapSquare:该属性值指定绘制方形端点.线条结尾处绘制半个边长为线条宽度的正方形.需要说明的是,这种形状的端点与“butt”形状的端点十分相似
//设置线条粗细宽度
CGContextSetLineWidth(context, 2.0);
//设置颜色,颜色为0-1之间
CGContextSetRGBStrokeColor(context, 0.90, 0.90, 0.90, 1.0);
// CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
//开始一个起始路径
CGContextBeginPath(context);
//起始点设置为(0,0):注意这是上下文对应区域中的相对坐标
CGContextMoveToPoint(context, 0, 0);
//设置下一个坐标点
CGContextAddLineToPoint(context, 100, 0);
//设置下一个坐标点
CGContextAddLineToPoint(context, 100, 100);
//设置下一个坐标点
CGContextAddLineToPoint(context, 0, 100);
CGContextAddLineToPoint(context, 0, 0);
//连接上面定义的坐标点
// CGContextStrokePath(context);
CGFloat arr[] = {8,1};
//下面最后一个参数“2”代表排列的个数。
CGContextSetLineDash(context, 0, arr, 2);
CGContextDrawPath(context, kCGPathStroke);
} ```
######CGContextRef的绘图相关函数
* `void CGContextClearRect(CGContextRef c, CGRect rect);
擦除指定矩形区域上绘制的图形`
* `void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode);使用指定模式绘制当前CGContextRef中所包
含的路径。第二个参数支持 kCGPathFill、kCGPathEOFill、kCGPathStroke、kCGPathFillStroke、kCGPathEOFillStroke等枚举值`
* `void CGContextEOFillPath(CGContextRef c);
使用奇偶规则来填充该路径包围的区域。奇偶规则指:如果某个点被路径包围了奇数次,系统绘制该点;如果被路径包围了偶数次,系统不绘制该点`
* `void CGContextFillPath(CGContextRef c);
填充该路径包围的区域`
* `void CGContextFillRect(CGContextRef c,CGRect rect);
填充rect代表的矩形`
* `void CGContextFillRects(CGContextRef c,const CGRect rects[], size_t count);
填充多个矩形`
* `void CGContextFillEllipseInRect(CGContextRef context, CGRect rect);
填充rect矩形的内切椭圆区域`
* `void CGContextStrokePath(CGContextRef c);
使用当前 CGContextRef设置的线宽绘制路径`
* `void CGContextStrokeRect(CGContextRef c, CGRect rect);
使用当前 CGContextRef设置的线宽绘制矩形框
void CGContextStrokeRectWithWidth(CGContextRef c,`
* `CGRect rect, CGFloat width);
使用指定线宽绘制矩形框`
* `void CGContextReplacePathWithStrokedPath(CGContextRef c);
使用绘制当前路径时覆盖的区域作为当前CGContextRef
中的新路径。举例来说,假如当前CGContextRef包含一个圆形路径且线宽为10,调用该方法后,当前CGContextRef将包含一个环宽为10的环形路径`
* `void CGContextStrokeEllipseInRect(CGContextRef context,CGRect rect);
使用当前 CGContextRef设置的线宽绘制rect矩形的内切椭圆`
* `void CGContextStrokeLineSegments(CGContextRef c,
const CGPoint points[], size_t count);
使用当前 CGContextRef设置的线宽绘制多条线段。该
方法需要传入2N个CGPoint组成的数组,其中1、2个点
组成第一条线段,3、4个点组成第2条线段,以此类推`
######设置绘图属性的相关函数
* `void CGContextSaveGState(CGContextRef c);
保存CGContextRef当前的绘图状态,方便以后恢复该状态`
* `void CGContextRestoreGState(CGContextRef c);
把CGContextRef的状态恢复到最近一次保存时的状态`
* `CGInterpolationQuality CGContextGetInterpolation
Quality(CGContextRef c);
获取当前CGContextRef在放大图片时的插值质量`
* `void CGContextSetInterpolationQuality(CGContextRef c,
CGInterpolationQuality quality);
设置当前CGContextRef在放大图片时的插值质量`
* `void CGContextSetLineCap(CGContextRef c, CGLineCap cap);
设置线段端点的绘制形状。该属性支持如下三个值。`
* `kCGLineCapButt:该属性值指定不绘制端点,
线条结尾处直接结束。这是默认值。`
* `kCGLineCapRound:该属性值指定绘制圆形端点,
线条结尾处绘制一个直径为线条宽度的半圆。`
* `kCGLineCapSquare:该属性值指定绘制方形端点。
线条结尾处绘制半个边长为线条宽度的正方形。需要
说明的是,这种形状的端点与“butt”形状的端点十分相似,只是采用这种形式的端点的线条略长一点而已`
* `void CGContextSetLineDash(CGContextRef c,
CGFloat phase, const CGFloat lengths[],size_t count);
设置绘制边框时所用的点线模式,Quartz 2D支持非常强大的点线模式.`
* `void CGContextSetLineJoin(CGContextRef c, CGLineJoin join);
设置线条连接点的风格`
* `void CGContextSetLineWidth(CGContextRef c, CGFloat width);
设置绘制直线、边框时的线条宽度`
* `void CGContextSetMiterLimit(CGContextRef c, CGFloat limit);
当把连接点风格设为meter风格时,该方法用于控制锐角箭头的长度`
* `void CGContextSetPatternPhase(CGContextRef c, CGSize phase);
设置该CGContextRef采用位图填充的相位`
* `void CGContextSetFillPattern(CGContextRef c,
CGPatternRef pattern,const CGFloat components[]);
设置该CGContextRef使用位图填充`
* `void CGContextSetShouldAntialias(CGContextRef c, bool shouldAntialias);
设置该CGContextRef是否应该抗锯齿(即光滑图形曲线边缘)`
* `void CGContextSetStrokePattern(CGContextRef c,
CGPatternRef pattern, const CGFloat components[]);
设置该CGContextRef使用位图绘制线条、边框
续表`
* `void CGContextSetBlendMode(CGContextRef context,CGBlendMode mode);
设置CGContextRef的叠加模式。Quartz 2D
支持多种叠加模式`
* `void CGContextSetAllowsAntialiasing(CGContextRef context, bool allowsAntialiasing);
设置该CGContextRef是否允许抗锯齿`
* `void CGContextSetAllowsFontSmoothing(CGContextRef context, bool allowsFontSmoothing);
设置该CGContextRef是否允许光滑字体`
* `void CGContextSetShouldSmoothFonts(CGContextRef c,bool shouldSmoothFonts);
设置该CGContextRef是否允许光滑字体`
* `void CGContextSetAlpha (CGContextRef c, CGFloat alpha);
设置全局透明度`
* `void CGContextSetCMYKFillColor(CGContextRef c,
CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha);
使用CMYK颜色模式来设置该CGContextRef的填充颜色`
* `void CGContextSetCMYKStrokeColor(CGContextRef c,
CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha);
使用CMYK颜色模式来设置该CGContextRef的线条颜色`
* `void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color);
使用指定颜色来设置该CGContextRef的填充颜色`
* `void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color);
使用指定颜色来设置该CGContextRef的线条颜色`
* `void CGContextSetGrayFillColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用灰色来设置该CGContextRef的填充颜色`
* `void CGContextSetGrayStrokeColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用灰色来设置该CGContextRef的线条颜色`
* `void CGContextSetRGBFillColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用RGB颜色模式来设置该CGContextRef的填充颜色`
* `void CGContextSetRGBStokeColor(CGContextRef c, CGFloat gray, CGFloat alpha);
使用RGB颜色模式来设置该CGContextRef的线条颜色`
* `void CGContextSetShadow(CGContextRef context,
CGSize offset, CGFloat blur);
设置阴影在X、Y方向上的偏移,以及模糊度(blur值越大,阴影越模糊)。该函数没有设置阴影颜色,默认使用1/3透明的黑色(即RGBA{0, 0, 0, 1.0/3.0})作为阴影颜色`
* `void CGContextSetShadowWithColor(CGContextRef context,
CGSize offset, CGFloat blur, CGColorRef color);
设置阴影在X、Y方向上的偏移,以及模糊度和阴影的颜色`