博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
layoutsubviews方法调用论证
阅读量:6688 次
发布时间:2019-06-25

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

hot3.png

layoutsubviews方法调用论证

在网上随便一搜layoutSubviews,就能搜到一大堆资料,其中见到最多就数下面这六句话了。今天我就一条条来验证这些观点。

1、init初始化不会触发layoutSubviews   但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发2、addSubview会触发layoutSubviews3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化4、滚动一个UIScrollView会触发layoutSubviews5、旋转Screen会触发父UIView上的layoutSubviews事件6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

一、init初始化不会触发layoutSubviews 但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发

1.)init

[super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    self.view.backgroundColor = [UIColor whiteColor];    _testView = [[UIImageView alloc] init];    [self.view addSubview:_testView];

在这里我预先通过runtime交换了系统的layoutSubviews、addSubview方法,然后在系统调用的时候打印出本次方法的调用者的class。控制器代码如上,运行得出了如下结果

1240

init-log.png

需要提一下状态栏有好几个视图,由于和主题无关就把一部分log给屏蔽了,感兴趣的可以在结尾看。

--根据结果来看 UIImageView并没有调用layoutsubviews。--

2.)initWithFrame

_testView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];

日志如下

1240

initWithFrame-log.png

--可以看到在控制器的view调用之后,UIImageView调用了layoutsubviews方法--

3.)initWithFrame:CGRectZero

_testView = [[UIImageView alloc] initWithFrame:CGRectZero];

日志如下

1240

initWithFrame CGRectZero-log.png

--结果和第一次一样--

综上所述,论点一正确

二、addSubview会触发layoutSubviews

有了论点一的支持,我们论证第二点就容易多了

_testView = [[UIImageView alloc] init];    _testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];    [self.view addSubview:_testView];    [_testView addSubview:_testLabel];

从论证论点一的第一次测试中可以得出init初始化不会执行layoutsubviews,代码如上,运行

1240

addsubview-log.png

--根据结果来看论点二也正确--

三、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化

1.)frame不改变

代码如下:

- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    _testView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];    [self.view addSubview:_testView];}- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event { NSLog(@"--touchesBegan!--"); _testView.frame = CGRectMake(0, 0, 1, 1);}

日志如下

1240

setframe.png

frame改变有两种情况,一种size改变,一种origin改变
2.)size改变

- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event { NSLog(@"--touchesBegan!--"); _testView.frame = CGRectMake(0, 0, 1, 2);}

日志如下

1240

setframe-2.png

3.)origin改变

- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event { NSLog(@"--touchesBegan!--"); _testView.frame = CGRectMake(0, 1, 1, 1);}

日志如下

1240

setframe-origin.png

--根据结果来看这条并不准确。 准确来说 设置view的Frame会触发layoutSubviews,前提是前后view的size发生了变化!--

四、滚动一个UIScrollView会触发layoutSubviews

这一点其实有点不全面,滚动scrollView会触发谁的layoutsubviews,是scrollView本身?还是scrollView的子视图?不过无所谓,接下来我一一解答。

1.)不添加子视图

- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    [self.view addSubview:self.scrollView];    self.scrollView.frame = self.view.bounds;    self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height * 2);}
- (UIScrollView *)scrollView {    if (!_scrollView) {        _scrollView = [[UIScrollView alloc] init];        _scrollView.backgroundColor = [UIColor lightGrayColor];        _scrollView.showsVerticalScrollIndicator = NO;        _scrollView.showsHorizontalScrollIndicator = NO;        _scrollView.delegate = self;    }    return _scrollView;}

注意!这里为了避免scrollView的指示器干扰 所以就不添加这俩货了

日志如下

1240

scrollView-2.png

2.)添加子视图
viewDidLoad中添加这两句

self.testView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];    [self.scrollView addSubview:self.testView];

日志如下

1240

scrollView-3.png

--根据结果来看,这条论点正确,不过拜托说清楚好吧 很容易让人误解--

五、旋转Screen会触发父UIView上的layoutSubviews事件

我居然看不懂这条想表达什么,screen是指屏幕吗?父view又是相对谁而言? so这条先不论证了

六、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

代码如下

- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor whiteColor];    _testView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];    [self.view addSubview:_testView];    _secView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];    [_testView addSubview:_secView];}- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event { NSLog(@"--touchesBegan!--"); _secView.frame = CGRectMake(0, 0, 2, 2);}

日志如下

1240

viewframechange.png

--根据结果来看该论点正确--

最后说说开头提到的问题,在我们什么视图都不添加的情况下,应用在启动后,都添加了那些视图在窗口上。

1240

windows’s subviews.png

1240

UIStatusBarForegroundView-subviews.png

1240

timeItemView's change.png

  • 可以看到除了我们平时熟悉的UIWindow 还有一个UIStatusBarWindow也就是说状态栏也存在一个window,这个window在开机就存在。
  • 我们所看到的服务商、时间、电量、网络信号都分别是一个view,所属类也不同。不过,经过我的测试,这几个类有同一个父类:UIStatusBarItemView
  • 电池view包含一个子视图是imageView来展示电池的图标。
  • 闲的蛋疼了。。。。。

最后的最后

这个就不传代码了。。。

文中如果有错误请在评论指出,不胜感激!

1240

23247b12010cad5261662c902b2165ab.png

转载于:https://my.oschina.net/fadoudou/blog/833138

你可能感兴趣的文章
HDU - 1520 Anniversary party [树形dp]
查看>>
nginx搭建多个站点
查看>>
字符串运算符
查看>>
linux大全
查看>>
jq 鼠标旋转控制也能3d旋转
查看>>
Spring+Mybatis多数据库的配置
查看>>
线性表----单链表
查看>>
mysql 启动报错
查看>>
Git 与 GitHub
查看>>
Spring Cloud:多环境配置、eureka 安全认证、容器宿主机IP注册
查看>>
【leetcode】667. Beautiful Arrangement II
查看>>
【leetcode】955. Delete Columns to Make Sorted II
查看>>
JDK源码阅读-Integer
查看>>
Java修行之路
查看>>
接口(工厂模式&代理模式)
查看>>
3月个人随笔
查看>>
netty入门
查看>>
iOS 组件化流程详解(git创建流程)
查看>>
搜索关键字高亮显示,就比微信多个多音字搜索
查看>>
1303: [CQOI2009]中位数图
查看>>