文档章节

layoutsubviews方法调用论证

法斗斗
 法斗斗
发布于 2017/02/07 10:57
字数 1209
阅读 15
收藏 0
点赞 0
评论 0

layoutsubviews方法调用论证

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

1、init初始化不会触发layoutSubviews
   但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发
2、addSubview会触发layoutSubviews
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4、滚动一个UIScrollView会触发layoutSubviews
5、旋转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。控制器代码如上,运行得出了如下结果

init-log.png

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

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

2.)initWithFrame

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

日志如下

initWithFrame-log.png

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

3.)initWithFrame:CGRectZero

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

日志如下

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,代码如上,运行

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<UITouch *> *)touches withEvent:(UIEvent *)event {
   NSLog(@"--touchesBegan!--");
    _testView.frame = CGRectMake(0, 0, 1, 1);
}

日志如下

setframe.png


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

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

日志如下

setframe-2.png


3.)origin改变

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

日志如下

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的指示器干扰 所以就不添加这俩货了
日志如下

scrollView-2.png


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

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

日志如下

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<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"--touchesBegan!--");
    _secView.frame = CGRectMake(0, 0, 2, 2);
}

日志如下

viewframechange.png


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

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

windows’s subviews.png

UIStatusBarForegroundView-subviews.png

timeItemView's change.png

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

最后的最后

这个就不传代码了。。。
文中如果有错误请在评论指出,不胜感激!

23247b12010cad5261662c902b2165ab.png

本文转载自:

共有 人打赏支持
法斗斗
粉丝 20
博文 336
码字总数 6335
作品 0
杨浦
程序员
layoutSubviews总结

还是没有理解,浩哥让我在pagecontrol上加红点的demo,失败的原因,其中一点就是layoutsubviews方法会去掉我手动加的view所以没效果,解决方法是在layoutsubviews中加上要调用的方法。 ios ...

夕阳_jhe ⋅ 2015/09/23 ⋅ 0

ios layout机制相关方法

ios layout机制相关方法 - (CGSize)sizeThatFits:(CGSize)size - (void)sizeToFit ——————- - (void)layoutSubviews - (void)layoutIfNeeded - (void)setNeedsLayout ——————– - ......

iShown ⋅ 2016/01/18 ⋅ 0

iOS layoutSubviews 什么时候会被调用

init 方法不会调用layoutSubviews addSubview 会触发target view(被添加view的view)和其subview的layoutSubviews方法 setFrame 只有当设置的frame的参数的size与原来的size不同,才会触发其...

董桉远 ⋅ 2014/08/17 ⋅ 0

iOS 开发小结之layoutSubviews调用

iOS 开发小结之layoutSubviews调用 iOS中的layoutSubviews是UIView的方法,该方法用于更精确的视图进行布局,可以在子类里重写这个方法。 开发过程中,了解layoutSubviews何时会被调用,从而...

法斗斗 ⋅ 2016/03/15 ⋅ 0

IOS中UIView的layoutSubviews和drawRect

UIView的setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。而set...

Erichkko ⋅ 2015/08/31 ⋅ 0

UIView的layoutSubviews和drawRect

UIView的setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。而set...

Megan_zhou ⋅ 2013/07/07 ⋅ 2

谈谈UIView的几个layout方法-layoutSubviews、layoutIfNeeded、

从百度上搜索了一下layoutSubviews的用处,以下是搜索的结果,当然,笔者是会一一验证的. 1、 init初始化不会触发layoutSubviews 2、 addSubview会触发layoutSubviews 3、 设置view的Frame会触发...

将来的你 ⋅ 2016/03/16 ⋅ 0

史上最详细最清楚的layoutSubView何时调用文章

1.init初始化 和 initWithFrame初始化都不会调用layoutSubView 2. addsubView会触发layoutSubViews, 当TestView.frame = {0,0,0,0}时; TestView *test = [[TestView alloc] init]; [sel......

王素年 ⋅ 2016/12/20 ⋅ 0

layoutSubviews何时调用的问题

今天跟旺才兄学习了一下UIView的setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentConte...

北方人在上海 ⋅ 2016/03/21 ⋅ 0

setNeedsDisplay和setNeedsLayout

1、UIView的setNeedsDisplay和setNeedsLayout方法 首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到 UIGraphicsGetCurrentContext,就可以画画了。而...

Karlon ⋅ 2016/05/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

CENTOS7防火墙命令记录

安装Firewall命令: yum install firewalld firewalld-config Firewall开启常见端口命令: firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --add-po......

cavion ⋅ 今天 ⋅ 0

【C++】【STL】利用chromo来测量程序运行时间与日志时间打印精确到微秒

直接上代码吧,没啥好说的。头疼。 #include <iostream>#include <string>#include <ctime>#include <sstream>#include <iomanip>#include <thread>#include <chrono>using ......

muqiusangyang ⋅ 今天 ⋅ 0

Mac环境下svn的使用

在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能,不过还需做一下简...

故久呵呵 ⋅ 今天 ⋅ 0

破解公司回应苹果“USB限制模式”:已攻破

本周四,苹果发表声明称 iOS 中加入了一项名为“USB 限制模式”的功能,可以防止 iPhone 在连接其他设备的时候被破解,并且强调这一功能并不是针对 FBI 等执法部门,为的是保护用户数据安全。...

六库科技 ⋅ 今天 ⋅ 0

MyBtais整合Spring Boot整合,TypeHandler对枚举类(enum)处理

概要 问题描述 我想用枚举类来表示用户当前状态,枚举类由 code 和 msg 组成,但我只想把 code 保存到数据库,查询处理,能知道用户当前状态,这应该怎么做呢?在 Spring 整合MyBatis 的时候...

Wenyi_Feng ⋅ 今天 ⋅ 0

synchronized与Lock的区别

# <center>王梦龙的读书笔记第一篇</center> ## <center>-synchronized与Lock的区别</centre> ###一、从使用场景来说 + synchronized 是能够注释代码块、类、方法但是它的加锁是和解锁使用一......

我不想加班 ⋅ 今天 ⋅ 0

VConsole的使用

手机端控制台打印输出,方便bug的排查。 首先需要引入vconsole.min.js 文件,然后在文件中创造实例。就能直接使用了。 var vConsole = new VConsole(); vConsole的文件地址...

大美琴 ⋅ 今天 ⋅ 0

Java NIO之字符集

1 字符集和编解码的概念 首先,解释一下什么是字符集。顾名思义,就是字符的集合。它的初衷是把现实世界的符号映射为计算机可以理解的字节。比如我创造一个字符集,叫做sex字符集,就包含两个...

士别三日 ⋅ 今天 ⋅ 0

Spring Bean基础

1、Bean之间引用 <!--如果Bean配置在同一个XML文件中,使用local引用--><ref bean="someBean"/><!--如果Bean配置在不同的XML文件中,使用ref引用--><ref local="someBean"/> 其实两种......

霍淇滨 ⋅ 今天 ⋅ 0

05、基于Consul+Upsync+Nginx实现动态负载均衡

1、Consul环境搭建 下载consul_0.7.5_linux_amd64.zip到/usr/local/src目录 cd /usr/local/srcwget https://releases.hashicorp.com/consul/0.7.5/consul_0.7.5_linux_amd64.zip 解压consu......

北岩 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部