博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
layoutSubview调用问题 含证明及特殊情况
阅读量:4143 次
发布时间:2019-05-25

本文共 3444 字,大约阅读时间需要 11 分钟。

文章目录

调用场景

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

若有误,敬请斧正。

转载地址:http://awkti.baihongyu.com/

你可能感兴趣的文章
转载知乎-前端汇总资源
查看>>
JavaScript substr() 方法
查看>>
JavaScript slice() 方法
查看>>
JavaScript substring() 方法
查看>>
HTML 5 新的表单元素 datalist keygen output
查看>>
(转载)正确理解cookie和session机制原理
查看>>
jQuery ajax - ajax() 方法
查看>>
将有序数组转换为平衡二叉搜索树
查看>>
最长递增子序列
查看>>
从一列数中筛除尽可能少的数,使得从左往右看这些数是从小到大再从大到小...
查看>>
判断一个整数是否是回文数
查看>>
经典shell面试题整理
查看>>
腾讯的一道面试题—不用除法求数字乘积
查看>>
素数算法
查看>>
java多线程环境单例模式实现详解
查看>>
将一个数插入到有序的数列中,插入后的数列仍然有序
查看>>
在有序的数列中查找某数,若该数在此数列中,则输出它所在的位置,否则输出no found
查看>>
万年历
查看>>
作为码农你希望面试官当场指出你错误么?有面试官这样遭到投诉!
查看>>
好多程序员都认为写ppt是很虚的技能,可事实真的是这样么?
查看>>