iOS:UIView类中 drawRect 方法理解

  drawRect 简介:

  一般情况下,该方法在视图加载过程中不做任何的使用和处理。当 UIView 的子类使用 core Graphics 和 UIKit 绘制视图内容时就需要在该方法中添加绘制的代码。

1 @interface UIView(UIViewRendering)
2 
3 - (void)drawRect:(CGRect)rect;

  该方法定义在 UIView(UIViewRendering) 分类里面,主要进行视图的绘制。

  不建议使用 Core Graphics 绘图,使用 CAShapeLayer 搭配 贝塞尔曲线已经能完成大部分需求,且与 Core Graphics 相比可节省大量内存占用。

  drawRect 示例:画一个矩形

 1 - (void)drawRect:(CGRect)rect {
 2 // Drawing code.
 3 //获得处理的上下文
 4 CGContextRef context = UIGraphicsGetCurrentContext();
 5 //设置线条样式
 6 CGContextSetLineCap(context, kCGLineCapSquare);
 7 //设置线条粗细宽度
 8 CGContextSetLineWidth(context, 1.0);
 9 //设置颜色
10 CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
11 //开始一个起始路径
12 CGContextBeginPath(context);
13 //起始点设置为(0,0):注意这是上下文对应区域中的相对坐标,
14 CGContextMoveToPoint(context, 0, 0);
15 //设置下一个坐标点
16 CGContextAddLineToPoint(context, 100, 100);
17 //设置下一个坐标点
18 CGContextAddLineToPoint(context, 0, 150);
19 //设置下一个坐标点
20 CGContextAddLineToPoint(context, 50, 180);
21 //连接上面定义的坐标点
22 CGContextStrokePath(context);
23 }

  core Graphics API:

 1 CGContextRef context = UIGraphicsGetCurrentContext(); // 获取上下文
 2 CGContextMoveToPoint  // 开始画线
 3 CGContextAddLineToPoint // 画直线
 4 CGContextAddEllipseInRect // 画一椭圆
 5 CGContextSetLineCap // 设置线条终点形状
 6 CGContextSetLineDash // 画虚线
 7 CGContextAddRect // 画一方框
 8 CGContextStrokeRect // 指定矩形
 9 CGContextStrokeRectWithWidth // 指定矩形线宽度
10 CGContextStrokeLineSegments // 一些直线
11 CGContextAddArc // 画曲线 前两点为中心 中间俩点为起始弧度 最后一数据为0则顺时针画 1则逆时针
12 CGContextAddArcToPoint //先画俩条线从point 到 第1点, 从第1点到第2点的线 切割里面的圆
13 CGContextSetShadowWithColor // 设置阴影
14 CGContextSetRGBFillColor // 只填充颜色
15 CGContextSetRGBStrokeColor // 画笔颜色设置
16 CGContextSetFillColorSpace // 颜色空间填充
17 CGConextSetStrokeColorSpace // 颜色空间画笔设置
18 CGContextFillRect // 补充当前填充颜色的rect
19 CGContextSetAlaha // 透明度
20 CGContextTranslateCTM // 改变画布位置
21 CGContextSetLineWidth // 设置线的宽度
22 CGContextAddRects // 画多个线
23 CGContextAddQuadCurveToPoint // 画曲线
24 CGContextStrokePath // 开始绘制图片
25 CGContextDrawPath // 设置绘制模式
26 CGContextClosePath // 封闭当前线路

  drawRect 作用:

  // Only override drawRect: if you perform custom drawing.

  // An empty implementation adversely affects performance during animation.

  重绘作用:重写该方法以实现在 View 上自定义的绘制内容。

  drawRect 调用时机:

  • 视图第一次显示的时候会调用。这个是由系统自动调用的,主要是在 UIViewController 中 loadView 和 viewDidLoad 方法调用之后。所以不用担心在控制器中, 这些View 的 drawRect 就开始画了。这样可以在控制器中设置一些值给 View (如果这些View draw的时候需要用到某些变量值)。
  • 如果在 UIView 初始化时没有设置 rect 大小,将直接导致 drawRect 不被自动调用。
  • 该方法在调用 sizeThatFits 后被调用, 所以可以先调用 sizeToFit 计算出 size, 然后系统自动调用 drawRect: 方法。
  • 通过设置 contentMode 属性值为 UIViewContentModeRedraw, 那么将在每次设置或更改 frame 的时候自动调用 drawRect:。
  • 直接调用 setNeedsDisplay,或者 setNeedsDisplayInRect: 触发 drawRect:,但是有个前提条件是 rect 不能为0。

  drawRect 重绘方法定义:

  • - (void)drawRect:(CGRect)rect; 重写此方法,执行重绘任务。
  • - (void)setNeedsDisplay; 标记为需要重绘,异步调用 drawRect,但是绘制视图的动作需要等到下一个 绘制周期 执行,并非调用该方法立即执行。
  • - (void)setNeedsDisplayInRect:(CGRect)rect; 标记为需要局部重绘,具体调用时机同上。

  drawRect 使用注意事项:

  • 如果子类直接继承自 UIView, 则在 drawRect 方法中不需要调用 super 方法。若子类继承自其他 View 类则需要调用 super 方法以实现重绘。
  • 若使用 UIView 绘图,只能在 drawRect: 方法中获取绘制视图的 contextRef。在其他方法中获取的 contextRef 都是不生效的。
  • drawRect: 方法不能手动调用,需要调用实例方法 setNeedsDisplay 或者 setNeedsDisplayInRect, 让系统自动调用该方法。
  • 若使用 CALayer 绘图,只能在 drawInContext:(类似于 drawRect:)绘制,或者在 delegate 方法中进行绘制,然后调用 setNeedDisplay 方法实现最终的绘制。
  • 若要实时画图,不能使用 gestureRecognizer,只能使用 touchbegan 等方法来掉用 setNeedsDisplay 实时刷新屏幕 ------这个阐述需要调整
  • UIImageView 继承自UIView, 但是 UIImageView 能不重写 drawRect 方法用于实现自定义绘图。

  

参考链接:

[UIVIew]谈谈对drawRect的理解

iOS重绘机制drawRect

DrawRect

http://www.jianshu.com/p/4db5f01b258e

iOS 关于Nib加载时候喜欢重写drawRect的恶习

 

posted @ 2017-11-06 15:53  鳄鱼不怕牙医不怕  阅读(1951)  评论(0编辑  收藏  举报