Swift Academy · 课时

测量子视图

在布局期间查询子视图尺寸。

第 2 / 4 课13 个步骤

测量子视图 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

测量驱动布局

在放置子视图之前,您必须先测量它们。SwiftUI 布局是一个协商过程:父视图提出尺寸建议,子视图作出响应,然后您协调这些结果。

询问子视图的尺寸

Subviews 中的每个代理对象都会针对给定的 ProposedViewSize 回答 sizeThatFits(_:)。代理对象会返回子视图在该建议下所采用的尺寸。

let size = subview.sizeThatFits(.unspecified)

三种探测尺寸建议

要了解子视图的适应性,请通过三种方式进行探测:.zero 显示其最小尺寸,.infinity 显示其最大尺寸,而 .unspecified 显示其理想尺寸。

let minSize = subview.sizeThatFits(.zero)
let maxSize = subview.sizeThatFits(.infinity)
let ideal = subview.sizeThatFits(.unspecified)

提出具体宽度

对于需要换行的文本,请提出一个具体的宽度,并将高度设为 nil。子视图会报告在该宽度下所需的高度。

let proposal = ProposedViewSize(width: 200, height: nil)
let fit = subview.sizeThatFits(proposal)

布局优先级

每个子视图都会公开一个 priority(由 .layoutPriority 设置)。空间紧张时,请先为优先级较高的子视图提供其理想尺寸。

for subview in subviews {
    let p = subview.priority
    // distribute space to higher priority first
}

读取自定义值

子视图可以通过 LayoutValueKey 携带类型化数据。布局读取 subview[MyKey.self] 来影响放置方式,例如设置每个项目的间距。

private struct RankKey: LayoutValueKey {
    static let defaultValue: Int = 0
}
let rank = subviews[0][RankKey.self]

设置布局值

视图通过 layoutValue(key:value:) 修饰符设置其布局值,让子视图能够向您的布局传递提示。

Text("Featured").layoutValue(key: RankKey.self, value: 10)

子视图之间的间距

子视图会公开 spacing 偏好。请使用 subview.spacing.distance(to:along:) 获取沿某个轴的两个相邻子视图之间的建议间距。

let gap = subviews[0].spacing.distance(
    to: subviews[1].spacing, along: .horizontal)

累积尺寸

水平布局会累加子视图的宽度,并取最高的高度。先测量所有子视图,您就可以在放置任何内容之前计算出容器尺寸。

let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
let totalWidth = sizes.reduce(0) { $0 + $1.width }
let maxHeight = sizes.map(\.height).max() ?? 0

放置期间重新测量

在 placeSubviews 中,您必须重新测量(或重新使用缓存的尺寸),以确保位置与您报告的尺寸相匹配。测量是开销很低的代理调用,并不是真正的渲染。

func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
    for s in subviews {
        let size = s.sizeThatFits(.unspecified)
        // use size to position s
        _ = size
    }
}

遵循父视图的提议

请始终遵循您收到的提议。如果父视图提议了固定宽度,请在该宽度内排列子视图;不要默默溢出,否则布局会被裁剪。

let containerWidth = proposal.width ?? .infinity

快速检查:测量

请测试您对测量子视图的理解。

回顾:测量子视图

测量是自定义布局的核心。请使用 .zero、.infinity 和 .unspecified 探测子视图,以了解最小、最大和理想尺寸;为可换行内容提议具体宽度,并遵循布局优先级和间距偏好。

自定义 LayoutValueKey 值可以让子视图传递提示。在协议的两个方法中保持一致的测量方式,以确保报告的尺寸和放置结果始终一致。

免费开始

用 AI 导师学习 Swift — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
122
课程
409

常见问题解答

「测量子视图」课时是免费的吗?

是的 — 「测量子视图」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「测量子视图」这节课中我会学到什么?

在布局期间查询子视图尺寸。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「测量子视图」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Layout 协议基础
  2. 测量子视图
  3. 构建流式布局
  4. 布局缓存与性能
← 返回 Swift Academy