UIView的布局更新和重绘机制

Laying out Subviews

-layoutSubviews

此函数用于,父视图的布局、大小等发生了改变,你想要同时更新其子视图的布局时,更新子视图布局的代码应写在父类重写后的layoutSubviews里(它默认不做任何事),但这时就不能在外部设置子视图的布局了。

注:初始化含frame(且显示出来)或改变frame,addSubview,滚动UIScrollView,旋转屏幕,改变子view的大小会触发layoutSubviews。

-setNeedsLayout

设置布局刷新标记——标记为需要重新布局。此方法会异步触发layoutSubviews(执行完成后刷新标记又置为NO),如果想立刻触发,应立刻调用layoutIfNeeded。

-layoutIfNeeded(写在animation内,用于实现更新约束时的动画效果)

配合setNeedsLayout,在有刷新标记的情况下立刻触发layoutSubviews。但在view的init方法后、第一次显示前(addSubview前),标记是“需要刷新”的。

self.testView= [[LayoutTestViewalloc]initWithFrame:CGRectMake(0,0,300,300)];  //初始化会调用两次setNeedsDisplay

//此时视图标记是“需要刷新”的,直接调用[self.testView layoutIfNeeded];会触发layoutSubviews,但之后的addSubview就不触发了

[self.view addSubview:self.testView]; //默认触发layoutSubviews

self.testView.frame = CGRectMake(0,0,500,500); //改变frame会再次触发layoutSubviews()

- (void)click {

      [self.testView setNeedsLayout]; //标记为可刷新且异步触发layoutSubviews

      [self.testView layoutIfNeeded]; //立刻触发layoutSubviews

      //只触发一次

}

Drawing and Updating the View

-drawRect:(CGRect)rect(内存杀手)

view首次显示或调用setNeedsDisplay时执行。

重写此方法,执行自定义绘制内容任务。默认不起作用。永远不要直接调用drawRect。重写此方法多用于UIView结合CGContextRef的手动绘图(与CALayer对应的是drawInContext)

CGContextRef ctx =UIGraphicsGetCurrentContext(); //获取当前画板(图形上下文,只在UIView的drawRect中有效)(还可以使用)

注:view重写drawRect后如果不指定背景色或把opaque设成NO背景将变黑。

实际需求:1、在当前画板上画图像,曲线、虚线、几何图形、写字等等。

2、UITextView添加自定义placeholder的需求中,将holder的label添加在写drawRect内,设置holder字符串时调用setNeedsDisplay重绘UITextView。

-setNeedDisplay

在下一个绘画周期(1/60秒后)主动触发drawRect执行重绘。setNeedDisplayInRect方法可限定在rect范围内重绘。一般结合重写drawRect来使用。

你可能感兴趣的:(UIView的布局更新和重绘机制)