内容简介:级别: ★★☆☆☆标签:「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三栏布局(包括双飞翼布局和圣杯布局)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高性能Python
(美)戈雷利克、(英)欧日沃尔德 / 东南大学出版社 / 2015-2
你的Python代码也许运行正确,但是你需要运行得更快速。通过探讨隐藏在设计备选方案中的基础理论,戈雷利克和欧日沃尔德编著的《高性能Python》将帮助你更深入地理解Python的实现。你将了解如何定位性能瓶颈,从而显著提升高数据流量程序中的代码执行效率。 你该如何利用多核架构和集群?或者你该如何搭建一个可以自由伸缩而不会影响可靠性的系统?有经验的Python程序员将会学习到这类问题的具体解......一起来看看 《高性能Python》 这本书的介绍吧!