有时候需要正向传值,发现在init时候创建并初始化不太方便,下面我研究了以下几个方法:
一、layoutSubviews
1、直接调用setLayoutSubviews或setNeedsLayout触发
2、addSubview的时候触发layoutSubviews。
3、当view的frame发生改变的时候触发layoutSubviews。
4、第一次滑动UIScrollView的时候触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
网上找的,4和5我没验证通过,
但对于自动布局,会出现如下情况:
lab = [[UILabel alloc] init];
lab.text = @"sdfdsdsgg";
[self addSubview:lab];
[lab mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
}];
1、对于上面自动布局控件,创建执行后,会执行两次layoutSubviews,这个我不知道原因。
2、第6条理论失效
3、如果把创建代码放到layoutSubviews上,一开始不会死循环,如果再次触发layoutSubviews,就会出现死循环
所有对于layoutSubviews,不太满意,当然再这里修改数值还是不错的选择
二、drawRect
1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在 控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量 值).
2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。setNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘,iphone device的刷新频率是60hz,也就是1/60秒后重绘
以上1,2推荐;而3,4不提倡
三、willMoveToSuperview
感觉像是即将被add到父view后才执行,但有时候会多次执行,原因尚未知道,比如说当此被移除的时候,比如调用[sub removeFromSuperview],也会调用willMoveToSuperview的。
下面是我在同一个view中的调用顺序:
2017-12-05 17:00:25.580543+0800 SummaryTest[5573:3375394] -[LayoutView willMoveToSuperview:]
2017-12-05 17:00:25.596744+0800 SummaryTest[5573:3375394] -[LayoutView layoutSubviews]
2017-12-05 17:00:25.600508+0800 SummaryTest[5573:3375394] -[LayoutView drawRect:]
三个方法都有可能被多次执行,所以不能代替init,但可以兼顾优化。
网友评论