内容简介:级别: ★★☆☆☆标签:「iOS布局」「iOS frame」「iOS frame bounds」作者: Xs·H
级别: ★★☆☆☆
标签:「iOS布局」「iOS frame」「iOS frame bounds」
作者: Xs·H
审校:QiShare团队
在沐灵洛 线下分享 iOS UIButton根据内容自动布局 时,有和前端同学讨论到iOS的常用布局方式。讨论过程十分热闹,不容易记录,但作者认为讨论结果有必要记录一下,希望能帮助到一些同学。 作者将iOS常用布局方式归纳为Frame、Autoresizing、Constraint、StackView和Masonry五种,并将逐一介绍。 本篇文章介绍 Frame
。
frame
是 UIView
的属性,用来描述 UIView
及其子类所表示的视图的位置( origin
)和大小( size
)。 frame
是 iOS
布局中最基本、最常用和最容易被开发者接受的布局方式。一般来说,可以通过以下方式很方便地创建并显示一个视图,如下。
- (void)viewDidLoad { [super viewDidLoad]; _contentView = [[QiFrameContentView alloc] initWithFrame:self.view.bounds]; _contentView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:_contentView]; } 复制代码
在上述代码中,作者在 viewDidLoad
中,将一个浅灰色的 contentView
添加到了 self.view
上,并将其 frame
设置为了 self.view.bounds
。显然,作者希望浅灰色的 contentView
完全盖住 self.view
(默认白色)。使用模拟器运行一下,初始效果如作者所愿,但将模拟器旋转方向后,浅灰色的 contentView
没有一起旋转,在右侧漏出了一部分白色的 self.view
,如下。
上述现象其实是frame特性的一种表现。在仅使用frame来布局视图时,视图的位置和大小是被唯一确定了的,不会跟随父视图的变化而变化,除非在某个时间点再次设置了frame。
作者希望 contentView
可以跟着 self.view
一起旋转,始终保持完全覆盖的效果,于是做了如下修改。
- (void)viewDidLoad { [super viewDidLoad]; _contentView = [[QiFrameContentView alloc] initWithFrame:CGRectZero]; _contentView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:_contentView]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; _contentView.frame = self.view.bounds; } 复制代码
为实现想要的小伙,作者在 viewWillLayoutSubviews
方法中重新设置了 contentView
的 frame
,并将 viewDidLoad
中初始化 contentView
时设置的 frame
改为了 CGRectZero
。 因为在每一次self.view的frame变化后和self.view的子view发生变化前都会触发viewWillLayoutSubviews方法。
借鉴上面的原理,作者在 contentView
上添加 4
个 subView
,实现 4
等分的效果,如下图。
实现上图效果的代码如下:
- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _subView1 = [[UIView alloc] initWithFrame:CGRectZero]; _subView1.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:.6]; [self addSubview:_subView1]; _subView2 = [[UIView alloc] initWithFrame:CGRectZero]; _subView2.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:.6]; [self addSubview:_subView2]; _subView3 = [[UIView alloc] initWithFrame:CGRectZero]; _subView3.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:.6]; [self addSubview:_subView3]; _subView4 = [[UIView alloc] initWithFrame:CGRectZero]; _subView4.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:.6]; [self addSubview:_subView4]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; CGFloat margin = 20.0; CGFloat padding = 20.0; CGFloat width = (self.bounds.size.width - margin * 2 - padding) / 2; CGFloat height = (self.bounds.size.height - margin * 2 - padding) / 2; _subView1.frame = CGRectMake(margin, margin, width, height); _subView2.frame = CGRectMake(margin + width + padding, margin, width, height); _subView3.frame = CGRectMake(margin, margin + height + padding, width, height); _subView4.frame = CGRectMake(margin + width + padding, margin + height + padding, width, height); /* _subView4.qi_width = width; _subView4.qi_height = height; _subView4.qi_top = _subView3.qi_top; _subView4.qi_left = _subView3.qi_right + padding; */ } 复制代码
其中,通过打点可知 contentView
中的 layoutSubviews
方法与 viewController
中的 viewWillLayoutSubviews
方法成对触发,并且 layoutSubviews
晚于后者。
PS:bounds与frame有一定区别。
bounds只用来描述视图的尺寸,就像一页A4纸,不论把它放在桌子上还是地板上,它的bounds都不发生变化。
frame除了能够描述视图的尺寸外还能描述视图的位置。再如A4纸,从桌子上挪到地板上,它的frame就发生变化了。
另外,为了更方便、直观地使用 frame
布局视图,可以使用类似上面代码中注释的代码形式。具体的实现细节,可以在 QiLayoutDemo 中查看。
小编微信:可加并拉入《QiShare技术交流群》。
关注我们的途径有:
QiShare(微信公众号)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 等高布局常用几种方式
- iOS 常用布局方式之Autoresizing
- CSS——把“可以动的盒子”更优雅地展示:③ 常用的“布局”
- css经典布局系列三——三列布局(圣杯布局、双飞翼布局)
- 四种方法实现──三栏布局(圣杯布局、双飞翼布局)
- 浅谈CSS三栏布局(包括双飞翼布局和圣杯布局)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。