Skip to content

iOS 开发 - Auto Layouts

使用 Swift 进行 iOS 开发 - Auto Layout

Section titled “使用 Swift 进行 iOS 开发 - Auto Layout”

当你设计一个 iOS 应用并添加 UI 元素时,它们可能在某个设备屏幕尺寸或方向上看起来完美无缺。然而,当你将相同的应用运行在不同的设备上(例如更大的 iPhone、iPad 或横屏方向)时,UI 可能会出现对齐问题、拉伸变形,甚至元素可能移出屏幕。Auto Layout 是 Apple 强大的系统,用于创建自适应的用户界面,使其在所有支持的设备和方向上都能良好显示。

在本章中,我们将探讨如何使用 Auto Layout 约束(constraints)和 UIStackView 来构建灵活且响应式的 UI。首先创建一个新的单视图应用项目或使用现有项目。

让我们来演示这个问题。在 Main.storyboard 中向你的视图顶部中心添加一个 UILabel,再向右下角添加另一个 UILabel。

现在,预览一下它在不同设备或方向上的样子。在 Interface Builder 画布底部,点击 ‘View as: [当前设备]’ 按钮(例如 ‘View as: iPhone 15 Pro’)。这将打开一个面板,你可以在其中选择不同的设备和方向(竖屏/横屏)来预览你的布局。你可能会发现,“顶部居中”的 Label 在较宽屏幕上并不真正居中,“右下角”的 Label 在横屏或不同尺寸设备上可能位置错误或部分移出屏幕。

这是因为,在没有 Auto Layout 的情况下,元素是使用相对于其父视图左上角的固定坐标定位的。Auto Layout 允许你定义规则(约束),描述元素如何相对于彼此或其容器进行定位和调整大小,从而实现动态适应。

让我们使用约束来修复 Label 的位置。

  1. 在 Interface Builder 中选择“顶部居中”的 Label。
  2. 要将其水平居中:从 Label 按住 Control 键拖动到其 superview(主视图)。会弹出一个菜单。选择 ‘Center Horizontally in Safe Area’。(注意:‘Safe Area’ 确保内容不被刘海屏、状态栏等遮挡。旧教程可能提及 ‘Container’)。
  3. 要将其垂直定位在顶部附近:再次从 Label 按住 Control 键拖动到其 superview。选择 ‘Top Space to Safe Area’。这会为顶部边距创建一个约束。如果需要,你可以在 Size Inspector 中编辑其 constant 值。
  4. 如果 Label 的 intrinsic content size(固有内容尺寸)不足,它还需要宽度和高度约束。对于简单的 Label,固有尺寸通常就足够了。如果不够,你可以使用 Interface Builder 画布右下角的 ‘Add New Constraints’ 菜单(图钉图标),或从 Label 本身按住 Control 键拖动并选择 ‘Width’ 和 ‘Height’ 来添加宽度/高度约束。

‘Add New Constraints’ 菜单(图钉图标)是同时添加多个约束的常用方式,例如前导/后导/顶部/底部间距、宽度、高度和宽高比(aspect ratio)。

  1. 选择“右下角”的 Label。
  2. 要将其固定在右下角:使用 ‘Add New Constraints’ 菜单(图钉图标)。将 ‘Trailing Space to Safe Area’ 和 ‘Bottom Space to Safe Area’ 设置为你想要的边距(例如 20 points)。确保你想添加的约束的红色实线(I-beam lines)是实心的,然后点击 ‘Add 2 Constraints’。 或者,从 Label 按住 Control 键拖动到 superview,选择 ‘Trailing Space to Safe Area’。重复此操作,从 Label 按住 Control 键拖动到 superview,选择 ‘Bottom Space to Safe Area’。

(提示:要从 control-drag 弹出菜单中同时选择多个约束选项,如果菜单支持,请在点击它们时按住 Shift 键,或者逐个添加它们。)

应用这些约束后,再次查看 ‘View as’ 面板。Label 现在应该在不同设备和方向上保持其预期的位置。Interface Builder 中的红色或橙色约束线表示需要解决的问题或模糊性。

UIStackView 提供了一种简化方式,用于水平或垂直排列视图集合。你为 Stack View 本身定义约束,然后它根据 axis(轴)、distribution(分布)、alignment(对齐)和 spacing(间距)等属性来管理其 arranged subviews(排列子视图)的布局。

让我们使用 Stack View 创建一个包含三个按钮的简单布局。想象一下,你想要两个按钮并排放置在顶部,并在它们下方有一个按钮,宽度横跨整个区域。

  1. 将三个 UIButton 实例拖放到你的视图上。暂时不必过于在意它们的精确初始位置。
  1. 选择顶部两个按钮(点击一个,然后按住 Command 键点击另一个)。
  2. 在选中两个按钮的情况下,点击 Interface Builder 画布底部的 ‘Embed In’ 按钮(看起来像一个箭头指向一个框),然后选择 ‘Stack View’。或者,前往 Editor > Embed In > Stack View。
  3. 默认情况下,这可能会创建一个垂直 Stack View。选择新创建的 Stack View。在 Attributes Inspector(属性检查器,右手边面板)中,将其 ‘Axis’ 改为 ‘Horizontal’。

在仍然选中这个水平 Stack View 的情况下,在 Attributes Inspector 中设置:

  • ‘Distribution’ 为 ‘Fill Equally’(这使得两个按钮在 Stack View 中占据相等的宽度)。
  • ‘Spacing’ 设置为一个期望的值,例如 ‘10’ points,以在按钮之间添加间距。
  1. 现在,选择水平 Stack View(包含两个按钮)以及第三个底部的按钮(按住 Command 键以同时选择两者)。
  2. 将这两个选定的项目嵌入到另一个 Stack View 中(使用 ‘Embed In’ 按钮或 Editor 菜单)。
  3. 选择这个新的外部 Stack View。在 Attributes Inspector 中,确保其 ‘Axis’ 为 ‘Vertical’。
  • 根据你期望的高度行为,将其 ‘Distribution’ 设置为 ‘Fill’ 或 ‘Fill Equally’。
  • 将 ‘Alignment’ 设置为 ‘Fill’,以使子视图(内部 Stack View 和底部按钮)拉伸到这个外部 Stack View 的宽度。
  • 将 ‘Spacing’ 设置为一个值,如 ‘10’ 或 ‘20’。

你的视图层级现在应该包含一个外部的垂直 Stack View,它包含一个内部的水平 Stack View(带两个按钮)和第三个按钮。

最后一步是为外部(垂直)Stack View 添加约束到其 superview。选择外部 Stack View。

  1. 使用 ‘Add New Constraints’ 菜单(图钉图标)。
  2. 将 ‘Leading Space to Safe Area’ 和 ‘Trailing Space to Safe Area’ 设置为边距(例如 20 points)。
  3. 将 ‘Top Space to Safe Area’ 设置为边距(例如 20 points)。
  4. 如果你希望它与底部保持特定距离,或者其内容不足以定义其高度,你可能还需要一个 ‘Bottom Space to Safe Area’ 约束。
  5. 点击 ‘Add X Constraints’。

现在,你的由嵌套 Stack Views 管理的包含三个按钮的布局应该能正确地适应不同的屏幕尺寸和方向。Stack Views 通过减少你需要管理的单个约束数量,极大地简化了复杂的布局。

Auto Layout 和 Stack Views 是现代 iOS UI 开发的基础。练习创建不同的布局以变得熟练。对于更复杂的场景,可以考虑使用 NSLayoutAnchor 进行程序化约束,以实现更精细的控制。