调用场景
- addSubview时会触发
- view的frame值发生改变会触发
- 滚动scrollView会触发
- 旋转屏幕会触发父view上的layoutSubview
- 改变UIView大小也会触发父View上的layoutSubview
代码显示及证明
为了显示清楚,我在自定义的scrollView和view里的layoutSubview函数加入打印
- (void)layoutSubviews {
[super layoutSubviews];
NSLog(@"scrollView layoutSubview");
}
- (void)layoutSubviews {
[super layoutSubviews];
NSLog(@"view layoutSubview");
}
在主视图里添加了一个自定义的exScrollView和一个自定义的exView,并在exView上添加了changeButton用于改变exView的frame,又在exView上添加了一个myView(继承自UIView)用于查看触发父View的形式。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_exView = [[TAYView alloc] init];
[self.view addSubview:_exView];
_exView.frame = CGRectMake(80, 200, 200, 100);
_exView.backgroundColor = [UIColor blackColor];
_myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
_myView.backgroundColor = [UIColor grayColor];
[_exView addSubview:_myView];
UIButton *changeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_exView addSubview:changeButton];
changeButton.frame = CGRectMake(10, 40, 100, 100);
[changeButton setTitle:@"change" forState:UIControlStateNormal];
[changeButton setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[changeButton addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];
_exScrollView = [[TAYScrollView alloc] init];
[self.view addSubview:_exScrollView];
_exScrollView.backgroundColor = [UIColor redColor];
_exScrollView.frame = CGRectMake(100, 100, 100, 50);
_exScrollView.contentSize = CGSizeMake(200, 50);
}
在button的点击事件里先改变exView的frame
- (void)press {
_exView.frame = CGRectMake(200, 200, 50, 50);
}
打印情况:
点击button后:
若将含有addSubview的代码注释,即
_exView = [[TAYView alloc] init];
// [self.view addSubview:_exView];
_exView.frame = CGRectMake(80, 200, 200, 100);
_exView.backgroundColor = [UIColor blackColor];
_exScrollView = [[TAYScrollView alloc] init];
// [self.view addSubview:_exScrollView];
_exScrollView.backgroundColor = [UIColor redColor];
则没有打印出的东西
故得知,先打印出的layoutSubview是由addSubview触发的,点击button后打印的是由改变frame触发的
1,2得证
滚动exScrollView
轻轻一拉就会打印很多 scrollView layoutSubview 故3得证
在button点击事件中加入myView的frame改变,即:
- (void)press {
_exView.frame = CGRectMake(200, 200, 50, 50);
_myView.frame = CGRectMake(5, 5, 30, 30);
}
点击button后打印情况:
但由上个测试可得,我们在改变exView的值时就已经调用了一次 view的layoutSubview了,是不是改变myView时没有调用呢,我们再次修改代码,只改变myView的frame:
- (void)press {
// _exView.frame = CGRectMake(200, 200, 50, 50);
_myView.frame = CGRectMake(5, 5, 30, 30);
}
还是只打印一次,故我们可知,layoutSubview是在所有布局完成后才调用
旋转屏幕的证明我与特殊情况一起解释。
特殊情况
在测试中实验室的小伙伴发现,设置exScrollView的位置不同,layoutSubview的触发次数不同,如下:
当我们将位置设置为(100,100,100,50)时,layoutSubview只打印一次
_exScrollView = [[TAYScrollView alloc] init];
[self.view addSubview:_exScrollView];
_exScrollView.backgroundColor = [UIColor redColor];
_exScrollView.frame = CGRectMake(100, 100, 100, 50);
_exScrollView.contentSize = CGSizeMake(200, 50);
将屏幕旋转,不打印
控制大小不变,当我们将位置设置为(10,10,100,50)时,layoutSubview打印两次
_exScrollView = [[TAYScrollView alloc] init];
[self.view addSubview:_exScrollView];
_exScrollView.backgroundColor = [UIColor redColor];
_exScrollView.frame = CGRectMake(10, 10, 100, 50);
_exScrollView.contentSize = CGSizeMake(200, 50);
将屏幕旋转,会打印
若注释addSubview,则两种位置都不打印
后重复测试发现临界值为20,高度20以下刚开始执行会触发两次并且旋转可触发,20以上刚开始只会触发一次旋转不可触发,模拟机状态栏高度刚好为20,故我们猜测此情况与状态栏有关。
若有误,敬请斧正。