setNeedsDisplay和setNeedsLayout和layoutSubviews和drawRect

setNeedsDisplay和setNeedsLayout都是异步执行的。

setNeedsDisplay

setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到 UIGraphicsGetCurrentContext,就可以画画了。

setNeedsLayout

而setNeedsLayout会默认调用layoutSubViews, 就可以处理子视图中的一些数据。

layoutSubviews调用方式:

1、init初始化不会触发layoutSubviews。
2、addSubview会触发layoutSubviews。
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
4、滚动一个UIScrollView会触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
7、直接调用setLayoutSubviews或setNeedsLayout。

drawRect在以下情况下会被调用:

1、 当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
2、 调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
3、 该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。前提条件是rect不能为0.
4、 通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。

  • drawRect方法使用注意点:

1、 如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。
2、drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.
3、若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate的ref并且不能用于画图。
4、drawRect:方法不能手动调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect等,让系统自动调该方法。
5、若使用calayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
6、若要实时画图,不能使用gesture Recognizer(手势触发),只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕

setNeedsDisplay调用drawRect与NSTimer造成屏幕卡顿:

setNeedsDisplay它会调用drawRect,它并不是立马,只是设了一个标志,当下一次屏幕刷新的调用。
所以当使用计时器的时候,NSTimer时间的设置,可能会造成卡顿
另一种方法可以将其加入runloop循环,runloop是屏幕刷新的时候调用:

    //创建CADisplayLink (当每一屏幕刷新就会调用 每一秒刷新60)
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

引用:http://blog.sina.com.cn/s/blog_a573f7990101cdpe.html

你可能感兴趣的:(setNeedsDisplay和setNeedsLayout和layoutSubviews和drawRect)