自动布局——Autoresizing

时代在进步,科技在发展,层出不穷的硬件在推动着软件技术发展的同时,也会随之而来一些烦恼。经历了十几年的进步,手机屏幕已经从原来硬币大小发展到现在各种材质、多种尺寸的局面。对于开发者来讲,随之而来的便是APP界面适配问题。

导致布局变化的原因

导致布局发生变化的原因可以分为外部原因和内部原因两种。

  1. 外部原因

    • 不同机型导致屏幕尺寸变化
    • 设备旋转
    • 来电和录音状态栏的显示与消失
  2. 内部原因

    • APP展示内容变化
    • APP支持国际化
    • APP支持动态展示

基于硬坐标的方式去布局只是能满足基本功能。由于上述原因导致界面重新布局时需要再次进行计算,界面设计越复杂计算量就越大,而自动布局相较于传统的硬坐标布局具有明显的优势。

布局方式的对比

硬坐标布局通过指定视图相较于父视图的原点距离和视图大小来定义视图布局。视图的布局很直观的展示在代码当中,但这种方式需要大量的努力来设计、调试和维护。

自动布局通过指定视图之间的约束关系来定义视图布局。这种方式在视图与视图之间建立了一种约束关系,变化是相互响应的,相较于硬坐标布局更加动态。

iOS中有两种自动布局的方法:Autoresizing MasksAuto Layout。接下来介绍一下Autoresizing Masks

Autoresizing Masks特性

autoresizingMaskUIView的属性,当view.autoresizeSubviewsYESview.bouns发生改变时,子视图会根据他们的autoresizingMask属性去自适应。

autoresizingMask是一个枚举默认类型,默认为UIViewAutoresizingNone

1
2
3
4
5
6
7
8
9
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

枚举值的说明:

属性名 说明
UIViewAutoresizingNone 不会随着父视图的改变而改变
UIViewAutoresizingFlexibleLeftMargin 自动调整view与父视图左边距,保证右边距不变
UIViewAutoresizingFlexibleWidth 自动调整view的宽度,保证左边距和右边距不变
UIViewAutoresizingFlexibleRightMargin 自动调整view与父视图右边距,保证左边距不变
UIViewAutoresizingFlexibleTopMargin 自动调整view与父视图上边距,保证下边距不变
UIViewAutoresizingFlexibleHeight 自动调整view的高度,保证上边距和下边距不变
UIViewAutoresizingFlexibleBottomMargin 自动调整view与父视图下边距,保证上边距不变

autoresizingMask是一个枚举类型,因此可以使用|将多个值分割开组合使用:

1
2
// view的宽度按照父视图的宽度比例进行缩放,距离父视图顶部距离不变
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin

Autoresizing Masks使用

代码实现

需求:保持B视图相较于父视图右边距和下边距不变

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
UIView *parentView = [[UIView alloc] initWithFrame:CGRectMake(20, 100, 200, 60)];
parentView.layer.borderColor = [UIColor blackColor].CGColor;
parentView.layer.borderWidth = 1.0f;

UILabel *bLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 60)];
bLabel.text = @"B视图";
bLabel.numberOfLines = 0;
bLabel.textAlignment = NSTextAlignmentCenter;
bLabel.textColor = [UIColor redColor];
bLabel.backgroundColor = [UIColor yellowColor];

[bLabel setAutoresizingMask: UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin];
[self.view addSubview:parentView];
[parentView addSubview:bLabel];

[parentView setFrame:CGRectMake(20, 100, 250, 160)];

实现效果:

Storyboard实现

由于Storyboard默认使用Auto Layout,需将Auto Layout取消勾选才可以使用Autoresizing


这里要说明一下,在使用Storyboard中的Autoresizing时,实线代表选中,虚线反之。
上实线代表子视图距离父视图上边距保持不变,这一点是与代码中UIViewAutoresizingFlexibleTopMargin不同的,需要注意。

总结

Autoresizing可以说它是对硬坐标布局的一种拓展以实现自动布局。相较于代码中使用Autoresizing,Storyboard中的使用方式更加直接,方便。