[Android开发学iOS系列] Auto Layout( 二 )

这个不但写起来麻烦, 可读性也很差.
Visual Format Language (VFL)let views = ["myView" : myView]let formatString = "|-[myView]-|"let constraints = NSLayoutConstraint.constraints(withVisualFormat: formatString, options: .alignAllTop, metrics: nil, views: views)NSLayoutConstraint.activate(constraints)用一些键盘符号来表达这个布局的. (like a way of drawing the layout you want with a series of keyboard symbols)
管道符号代表parent view的边边.
Auto Layout的工作原理

[Android开发学iOS系列] Auto Layout

文章插图
图来自于: https://developer.apple.com/videos/play/wwdc2018/220
Render loop包含如上三个阶段:
  • update constraints从叶子节点向上.
  • layout从parent节点向下执行.
  • display即最后的绘制阶段.
这三个阶段对应的方法:
[Android开发学iOS系列] Auto Layout

文章插图
Update Constraints它的工作是:
  • 把每个公式(约束)加入计算引擎Engine里.
  • 计算引擎负责解出变量: 最后的frame.
  • 通知View: Superview: setNeedsLayout().
engine这里扮演一个layout cache和tracker. 收到变化时它会重新计算.
Layout从engine得到信息后, Subview setBounds(), subview setCenter().
尺寸和优先级了解了Auto Layout的原理之后, 看尺寸和优先级的部分就很好理解.
Intrinsic content size有一些View有固有内容尺寸, 对于AutoLayout来说, 会默认使用intrinsic content size, 这样开发者就不用非得提供尺寸信息.
默认使用: intrinsic content size. 固有内容尺寸.
  • UIImageView: image size.
  • UILabel: text size.
优先级优先级的值可以从1到1000, 默认是1000.
  • Required: 1000
  • Default High: 750
  • Default Low: 250
有优先级是因为多个constraints之间可能会有冲突, 那么约束的要求可能不能完全100%满足, 计算引擎会在在不能满足的情况下, 尽量地减少偏差.
约束的优先级就用来表示哪条约束我们更加关心, 更想满足, 优先考虑.
优先级相关的变量
  • content hugging priority: 尺寸比固有内容更大的可能性. 默认250. 值越小表示View更愿意扩张来满足约束了; 值越大表示View希望尽可能地接近固有尺寸.
  • content compression resistance priority: 尺寸比固有内容尺寸更小的阻力程度. 默认750. 值越大表示这个View压缩内容的可能性越小.
Auto Layout的使用细则Properties & Functions有个重要的属性要提一下:
  • translatesAutoresizingMaskIntoConstraints
这个属性是为了兼容Auto Layout出现之前的基于frame布局的legacy layout系统, 帮助View在Auto Layout的世界里, 以legacy layout system的方式运作.
当这个属性为true, 并且设置了frame时, 引擎会自动生成constraints来满足这个frame.
这个View的属性默认为true. 当我们要用constraints时需要设置为false.
  • 当在storyboard中开始为View设置constraints时, 会自动设置为false.
  • 当我们在代码中给view设置约束之前, 需要自己显式地把这个属性设置为false.
如果还是用frame布局, 这个属性不用设置成false. 比如在循环里生成很多view的时候, 可能想有一些尺寸和位置用frame设置.
  • sizeToFit(): 刚好包裹内容的大小.
Stack ViewStack View是在Auto Layout的基础上的, 帮助我们做一些水平或者垂直的布局, 不用写内部元素间的constraints. (类似于Android中的LinearLayout.)
往Stack View里加需要叠放的元素用的是addArrangedSubview()这个方法.
与此同时, addSubview()方法可以用来加一些别的View.
几个属性:
  • axis: 主轴方向.
  • alignment: 对齐方式.
  • distribution: 沿着主轴的分布.
Stack View是比较轻量的, 所以官方会建议尽量多使用Stack View, 只在有必要的时候写约束.确实方便很多.
Layout Guide很多时候为了布局的需要我们可能要包裹View或者是添加一下辅助View, 每个View都有自己的layer, 所以为了改进性能, 我们可以使用Layout Guide.
View自带一个layoutMarginsGuide.
还挺方便的. (看了这个视频: https://www.youtube.com/watch?v=4qPcMGiSADA)
Performance & Building Efficient LayoutsiOS12对AutoLayout的性能做了很多改进, 这个WWDC的talk有讲.
关于有效率的布局, 简而言之就是少做无用功.
Constraint Churnconstraint churning是个典型的性能问题.churn: 搅动.
constraint churn是指更新了constraints, 但实际上view并不需要移动.
这样是给engine发送了额外的信息, 达到一定数量之后, 就会影响性能.

推荐阅读