iOS图形绘制之CGContextRef

今天做页面需要用到绘图绘制虚线,由于平时不怎么用到绘图,对绘图的基础也不是很好,所以写一篇关于绘图的文章,巩固下基础,并做下记录

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方向上的偏移,以及模糊度和阴影的颜色`
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 一、使用UIImage和CGImage处理图位 可用通过Quartz的图片对象或原始图片数据来创建UIImage。...
    MD_963阅读 1,566评论 0 3
  • 原文出处 http://blog.csdn.net/u014286994/article/details/5133...
    Poison_19ce阅读 1,431评论 0 2
  • --绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益...
    韩七夏阅读 2,686评论 2 10
  • Quartz2D以及drawRect的重绘机制字数1487 阅读21 评论1 喜欢1一、什么是Quartz2D Q...
    PurpleWind阅读 752评论 0 3
  • 目前市场上的减肥仪器大多数是通过局部振动按摩的方式,例如XX按摩器和XX甩脂机,他们宣称通过被动运动可以让脂肪碎片...
    mediphe阅读 440评论 0 0