AutoLayout布局

Posted by QingQue on 2020-06-10

苹果都出SwiftUI了,为什么要学AutoLayout?因为SwiftUI支持iOS13+、macOS10.15+,未来几年时间为了兼容老版系统,还得用AutoLayout布局。一直以来,我虽然在做iOS开发,但很少用storyboard做控件约束,所以本文主要用storyboard,介绍一些入门级概念。

相信能来看AutoLayout相关内容的同学,对iOS或者macOS开发已经了解的很多了,Frame、Bounds等概念就在赘述了。

AutoLayout是相对布局,只要你适应了这种布局方式,也很方便的,个人感觉比手撸代码快得多。

AutoLayout相关属性

属性 含义
top 顶部
bottom 底部
leading(left) 左边
trailing(right) 右边
height 高度
width 宽度
center X X轴中心
center Y Y轴中心
baseline 文字的基线位置

storyboard/xib中工具介绍

上面的五个按钮分别是:update frames, align,add new constaints,resolve autolayout issues,embed in。

update frames 作用是刷新frame,没什么好说的。

align 按钮点开之后,可以看到align面板上面有9种约束关系设置。其中前面7种需要同时至少选择2个控件后才能允许设置,其中最后2个Horizontally in Container和Vertically in Contaoner是约束选中的控件与父视图的关系。每种关系都可以通过右边的输入框输入一个constant常量,如果不输入默认为0。

add new constaints面板最上部用来设置选择的控件四个边top,bottom,leading,trailing距离父视图或相邻的控件之间的间距。
对需要设置的属性点击红色虚线后表示设置此方向的属性。

Width和Heigth用来设置控件的高和宽

Equal Widths: 选中的至少2个控件,约定它们的宽度相同

Equal Heigths:选中的至少2个控件,约定它们的高度相同

Aspect Ratio:选中控件,约定高度和宽度的比例关系。

Align:可以下拉选择不同的属性,类似通过Align面板设置的各种属性,因此这里可以代替大部分前面Align面板中大部分的约束设置的操作。

resolve autolayout issues面板中,上面一组菜单是当前选中控件的操作,下面一组是整个viewcontroller的操作。用于更新Frame,更新约束,自动增加缺少的约束,基于系统建议重置约束,删除约束。

embed in面板就是给当前view或者当前viewcontroller添加Stack View或者Navigation Controller。如果需要去掉Stack View,从Editor菜单选择Unembed 即可。

storyboard/xib中AutoLayout关系描述

当我们给一个view添加一些约束之后,会出现:

Constraints里面的某些表达式,看着一脸懵逼,那么这些表达式是什么意思呢?

例如:Safe Area.trailing = View.trailing + 20

当前view的右边距离 Safe Area的右边是20。

View.top = Safe Area.top + 137 当前view的顶部距离 Safe Area的顶部是137,也可以理解为Safe Area的顶部到view的顶部距离是137

Stack View.centerX = centerX @999 这条约束后面多了一个@999,999是该条越是的优先级,默认优先级是1000是不会在表达式中显示的,当某些情况下,两条约束产生冲突时,程序为按照优先级执行。

Size Classes(仅iOS)

注:iOS中才会Size Classes,macOS没有

很多同学在看到Size Classes时,脑海中无所个问号,根据官方的解释就是,对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松。这样开发者便可以无视设备具体的尺寸,而是对这两类和它们的组合进行适配。更通俗的理解就是,Size Classes把宽度和高度各分为3种情况(紧凑、任意、宽松),每条约束可以根据这紧凑,任意和宽松进行调整。

Any(任意):A

Regular(常规):R

Compact(紧凑):C

对应关系

iPad iPhone
竖屏 横屏
高(H) R R C
宽(W) R C C R(Plus)

看起很复杂?没关系,这个不需要记住,看一张图就明白了

在设备选择区域,可以看到 view as:iPhone 11(wC hR) ,其中括号中的wC hR是当前设备竖屏状态下高宽度对应关系,我这里选择的iPhone11 可以看到在竖屏状态下,宽度是Compact(紧凑),高度是Regular(常规)。注意在当前状态下添加的约束并不是只适用于当前状态。

在上图中,我们在文档大纲中选择了一条约束,在size inspector面板上出现了该约束的相关属性,在某些属性前面有一个+按钮,点击这个按钮会弹出图中的面板,面板中可以指定该约束的高宽度的对应关系,添加之后,会出现一条相同的属性,该属性既是我们指定的状态的属性,例如,在上面面板中,我们把宽度指定为Regular(常规),高度为Compact(紧凑),添加之后,改变值为100,那么在横屏状态下,该约束的值为100。如果需要对一条约束指定,可以点击installed属性前面的 + 按钮,添加对应的状态。

Intrinsic Content Size

对于文本/图片等一些视图控件,可以通过其内在content推算出控件的大小。不是所有的控件都有Intrinsic Content Size。按钮,文本label,文字输入TextField,TextView,ImageView都可以根据内在的content内容计算控件的大小。

基于控件的内容content,有2个特定的约束:content hugging 收缩约束 和 content compression 扩张约束,这2个约束简称为CHCR。

IntrinsicHeight代表内部内容的高,IntrinsicWidth代表内部内容的宽

content compression的约束条件:

1
2
View.height >= IntrinsicHeight
View.width >= IntrinsicWidth

content hugging的约束条件:

1
2
View.height <= IntrinsicHeight
View.width <= IntrinsicWidth

从这几组约束来看,如果需要完整的显示内容就需要content compression的优先级尽量高,而如果需要尽量显示的紧凑一些占用空间小一些可以将content hugging优先级尽量设置高一些。


分享到: