layoutSubview调用问题 含证明及特殊情况

调用场景

  • 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,故我们猜测此情况与状态栏有关。
若有误,敬请斧正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值