lufei's Studio.

iOS Auto Layout

字数统计: 723阅读时长: 2 min
2020/07/08 Share

前言

看了 钟颖大神的微博 之后,惭愧于自己关于 Auto Layout 知识的缺失,于是有了这篇文章。

钟大微博里的不太明白的词

  • RTL 一种书写方向,如阿拉伯文和希伯来文

  • A11Y 全称 Accessibility 指「可访问性」,在苹果的定义下指「无障碍使用」,Accessibility on iOS

  • Baseline 指基线,在 Auto Layout 的定义下,一般指「在视图底部上方放置文字的地方」

Cassowary 算法

Cassowary 能够有效解析线性等式系统和线性不等式系统,用户的界面中总是会出现不等关系和相等关系,Cassowary 开发了一种规则系统可以通过约束来描述视图间关系。约束就是规则,能够表示出一个视图相对于另一个视图的位置。

2011年苹果将这个算法运用到了自家的布局引擎中,也就是 Auto Layout。

Auto Layout 的生命周期

在得到自己的 layout 之前 Layout Engine 会将 Views ,约束,Priorities(优先级), instrinsicContentSize(主要是 UILabel, UIImageView 等)通过计算转换成最终的效果。

Layout Engine 的循环机制:

约束变化 -> Deferred Layout Pass -> 应用 Run Loop -> 约束变化

生命周期中需要注意的事项

  • 不要期望 frame 会立刻变化

  • 在重写 layoutSubviews() 时需要非常小心。

关于约束

Auto Layout 的视图层级里,所有视图通过放置在它们里面的约束来动态计算的它们的大小和位置。一般控件需要四个约束决定位置大小,如果定义了 intrinsicContentSize 的比如 UILabel 只需要两个约束即可。

IntrinsicContentSize / Compression Resistance Priority / Hugging Priority

具有 instrinsic content size 的控件,比如 UILabel ,UIButton ,选择控件,进度条和分段等等,可以自己计算自己的大小,比如 label 设置 text 和 font 后大小是可以计算得到的。

但是当同时有多个 Intrinsic Content Size 控件需要布局的时候,就会出现 「Intrinsic 冲突」,此时就需要 Compression Resistance Priority 和 Hugging Priority。

约束方程式

view1.attribute1 = mutiplier * view2.attribute2 + constant

Api 添加约束

NSLayoutConstraint 官方参考

VFL 语言添加约束

VFL 语言指南

UIStackView

由于前面两种方案过于麻烦,苹果还提供了 UIStackView

UIKit Framework Reference UIStackView Class Reference

布局过程

updateConstraints -> layoutSubViews -> drawRect

viewDidLayoutSubviews,-layoutSubviews

使用 Auto Layout 的 view 会在 viewDidLayoutSubviews 或 -layoutSubview 调用 super 转换成具有正确显示的 frame 值。

View 的改变会调用哪些方法

  • 改变 frame.origin 不会掉用 layoutSubviews

  • 改变 frame.size 会使 superVIew 的 layoutSubviews 调用

  • 改变 bounds.origin 和 bounds.size 都会调用 superView 和自己 view 的 layoutSubviews 方法

参考

Auto Layout Guide

深入剖析Auto Layout,分析iOS各版本新增特性

AutoLayout的一些基本概念

CATALOG
  1. 1. 前言
    1. 1.1. 钟大微博里的不太明白的词
  2. 2. Cassowary 算法
  3. 3. Auto Layout 的生命周期
    1. 3.1. 生命周期中需要注意的事项
  4. 4. 关于约束
    1. 4.1. IntrinsicContentSize / Compression Resistance Priority / Hugging Priority
    2. 4.2. 约束方程式
    3. 4.3. Api 添加约束
    4. 4.4. VFL 语言添加约束
    5. 4.5. UIStackView
  5. 5. 布局过程
    1. 5.1. viewDidLayoutSubviews,-layoutSubviews
    2. 5.2. View 的改变会调用哪些方法
  6. 6. 参考