drawRect:一点绘图知识总结

来源:互联网 发布:c语言加密程序2 编辑:程序博客网 时间:2024/06/10 05:01

1.当一个类是UIView或UIView的子类时,这个类会调用drawRect:用来绘制显示在手机屏幕的图片,通常我们把自定义的绘图时,会覆盖此方法并把代码写在这个方法里,每当UIView的实例要绘图或重绘时,系统会为这个View准备一个绘图上下文,然后这个上下文会被激活,drawRect:消息会被发送。绘图上下文的类型是CGContextRef负责合成绘图命令和生成图片,保存绘图状态。当我们调用UIKit框架中的类和方法,这是会隐式地使用当前激活的绘图上下文。在其他情况下你需要取得绘图上下文,然后调用Core Graphics框架的C函数来绘图。(Each time an instance of UIView needs to be drawn (or redrawn), the system prepares a graphics context specifically for that view. Then the context is activated, and the message drawRect: is sent to the instance of UIView that is being drawn. The graphics context’s type is CGContextRef (Core
Graphics Context Reference), and it is responsible for aggregating drawing commands and producing an image as a result. This image is the appearance of the view instance. A graphics context also stores its drawing state, which includes things like the current drawing color, coordinate system, and the
current line width.)

下面来分析一下代码:(摘自《ios编程》)

- (void)drawRect:(CGRect)rect {    CGRect bounds = [self bounds];        CGPoint center;    center.x = bounds.origin.x + bounds.size.width/2.0;    center.y = bounds.origin.y + bounds.size.height/2.0;    //计算半径    float maxRadius = hypot(bounds.size.width,bounds.size.height)/2.0;    //拿到绘图上下文    CGContextRef context = UIGraphicsGetCurrentContext();       //设置线条的宽度    CGContextSetLineWidth(context, 10);    //设置线条颜色    [[UIColor lightGrayColor] setStroke];        for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {        CGContextAddArc(context, center.x, center.y, currentRadius, 0.0, M_PI*2.0, YES);        CGContextStrokePath(context);    }     //创建字符串    NSString *text = @"you are getting sleepy.";        //获取所需的字体    UIFont *font = [UIFont boldSystemFontOfSize:28];        //计算绘图位置    CGRect textRect;    textRect.size = [text sizeWithFont:font];    textRect.origin.x = center.x - textRect.size.width/2.0;    textRect.origin.y = center.y - textRect.size.height/2.0;        //将当前上下文填充色设为黑色    [[UIColor blackColor] setFill];        //阴影设为右偏移4点,向下偏移3点,暗灰色,2点模糊半径    CGSize offset = CGSizeMake(4, 3);    CGColorRef color = [[UIColor darkGrayColor] CGColor];        CGContextSetShadowWithColor(context, offset, 2.0, color);   // CGContextStrokePath(context);    //绘制字符串    [text drawInRect:textRect withFont:font];   }

绘出来的效果如图:


按照我自己的理解是:

1.先拿到绘图上下文(相当于拿到一套画图的文具盒,包括画板,水彩笔什么的):CGContextRef context = UIGraphicsGetCurrentContext();。

2.然后设置线宽(相当于选择什么样大小的水彩笔,是大水的还是小水的),调用函数CGContextSetLineWidth(context, 10);。

3.设置线条颜色(找一支什么颜色的笔)。[[UIColor lightGrayColor] setStroke];   (setStroke:我的理解是设置到画(划)线当中)。

4.现在笔、画板(其实传进来的rect就是画板)都准备好了,接下来就是要给一条画的路径,即沿着什么样的路径来画。设置路径CGContextAddArc(context, center.x, center.y, currentRadius, 0.0, M_PI*2.0, YES);这个函数是画一个弧。

5.好了,开始画画:CGContextStrokePath(context);这个函数意思是沿着路径画线(有一个关于这个函数的知识点下面会更加详细介绍),前面已经说到上下文(context)的作用了,这里应该有一个更好的理解。传入上下文,按照上下文来画,前面就是设置绘图上下文,如颜色设置,线宽设置。

下面的绘制字体更多的调用了UIKit框架的方法。

(举的例子的逻辑应该跟函数调用的逻辑差不多吧)


2.关于CGContextStrokePath()函数

我在测试的过程中遇到了一些问题,当我添加CGContextStrokePath(context);到绘制字符串前面的时候,得出来的效果跟前面的图一样,context不是已经加了阴影了吗?为什么出来的图没添加呢,后来我把for循环里面的CGContextStrokePath(context);去掉,把[text drawInRect:textRect withFont:font];去掉(去掉这个是为了更好观察)。得到的结果是:(那一横我实在是搞不懂是什么原因,路径不是只有圆圈吗?求大神解答!)


那肯定是在CGContextStrokePath(context);做了某些手脚。查阅API得出来的结果是:

Quartz uses the line width and stroke color of the graphics state to paint the path. As a side effect when you call this function, Quartz clears the current path.

也就是画完后会把当前的路径清掉。

0 0
原创粉丝点击