UIView的drawRect和layoutSubviews方法

1、 drawRect重绘。
1)获取相应的contextRef,实现UIView的绘图和重绘。如果需自定义绘图效果,则需要重写此方法,示例如下:
- (void)drawRect:(CGRect)rect
{
  // 获得处理的上下文
  CGContextRef context = UIGraphicsGetCurrentContext();
  // 设置线条样式
  CGContextSetLineCap(context, KCGLineCapSquare);
  // 设置线条粗细...
  ......   
  // 开始一个起始路径
  CGContextBeginPath(context);
  // 设置起始点
  CGContextMoveToPoint(context, 0, 0);
  // 设置下一个坐标
  CGContextAddLinePoint(context, 0, 0);
  .......
  // 连接定义的坐标点
  CGContextStrokePath(context);
}

2)方法如何调用?什么时候调用?

视图的drawRect绘图方法,在控制器的loadView、viewDidLoad方法后执行,如此可在控制器的方法中设置相关属性。苹果建议重绘时不应手动调用该方法,应该通过setNeedsDisplay方法,让系统自动调用drawRect方法。(drawRect进入前提是视图的CGRect不为0)

在画图软件中,通过touchbegin等方法来调用setNeedsDisplay方法,而不是从gestureRecognizer,实时刷新屏幕。

在iphone device中,刷新频率是60HZ,因此理想情况会在1/60秒后,调用drawRect完成重绘。

 
2、setNeedDisplay刷新,此方法异步执行,不阻塞线程,会自动调用 drawRect 方法。
 
 
3、 layoutSubViews。官方说明:

The default implementation of this method does nothing on iOS 5.1 and earlier. Otherwise, the default implementation uses any constraints you have set to determine the size and position of any subviews.

Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly. 

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method. 

1)此方法除了用参数来设定subViews的尺寸和位置,其它啥也没干

2)如果自动布局后,效果不满意,可重写此方法,通过设置子视图的尺寸,添加更精确的布局

3)不要直接调用此方法。而是调用setNeedsLayout来刷新布局,或者调用layoutIfNeeded立即刷新视图。

实现subviews重新布局,layoutSubviews调用优先级>drawRect方法
被调用场景:
1)frame为0时,不会触发 layoutSubviews,而 initWithFrame: 或改变frame值时会触发。
2)addSubview 会触发 layoutSubviews。
3)滚动一个 UIScrollView 会触发 layoutSubviews。
4)旋转 Screen,会触发 superUIView 上的 layoutSubviews 事件。
5)改变视图大小时,也会触发 superUIView 上的 layoutSubviews 事件。

4、setNeedsLayout,异步执行方法。给receiver贴上需要被重新布局的标记,然后在系统下一个runloop周期,自动调用layoutSubviews。

5、layoutIfNeeded,方法遍历subviews链,对需要刷新的receiver发送layoutSubviews消息。
立即刷新步骤:先调用setNeedsLayout (把标记设为需要布局)》》》然后调用[view layoutIfNeeded]


你可能感兴趣的:(UIView的drawRect和layoutSubviews方法)