0Pricing
Swift Academy · 课时

理解视图身份

控制 SwiftUI 如何比较和复用视图。

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

标识驱动 SwiftUI

SwiftUI 会根据每个视图的标识跟踪它,以决定是更新现有视图还是创建新视图。

正确处理标识,是确保正确性和性能的最重要因素。

两种标识

SwiftUI 使用两种形式:结构标识(视图在视图树中的位置)和显式标识(由您分配的标识符)。

结构标识

默认情况下,视图的标识来自它在层级结构中的位置。下面的 if 分支会创建两个在结构上不同的视图。

var body: some View {
    if isOn {
        Text("On")  // one identity
    } else {
        Text("Off") // a different identity
    }
}

分支为何会丢失状态

由于每个分支具有不同的结构标识,在两个分支之间切换时,第一个视图会被销毁,第二个视图会被创建。其中的任何 @State 都会被重置。

if isExpanded {
    DetailView() // new instance each time the branch flips
} else {
    SummaryView()
}

使用 id() 设置显式标识

.id(_:) 修饰符会分配显式标识。更改标识符会告诉 SwiftUI“这是一个不同的视图”,从而强制创建新实例并重置状态。

CounterView()
    .id(selectedTab) // new identity per tab

ForEach 中的标识

ForEach 需要为每个元素提供稳定的标识。请使用指向稳定标识符的键路径,不要在可变集合中使用数组索引。

ForEach(items, id: \.id) { item in
    RowView(item: item)
}

索引标识陷阱

在会发生变化的索引或值上使用 id: \.self,会在数据发生变化时重新排列标识,从而导致错误的动画和状态丢失。

// Risky if items reorder or values repeat:
// ForEach(0..<items.count, id: \.self) { ... }

标识与动画

动画会在相同标识的状态之间进行插值。如果标识发生变化,SwiftUI 会执行插入或移除过渡,而不是平滑动画。

withAnimation {
    // same identity -> property animates
    // changed id     -> transition (fade/slide)
}

条件修饰符会改变标识

在 if 中应用修饰符可能会改变结构标识,从而重置状态。更好的做法是使用单个视图,并根据条件计算修饰符的值。

// Better: keep one identity
Text("Hi")
    .opacity(isHidden ? 0 : 1)
// Worse: branching creates two identities

AnyView 会抹除标识信息

将视图包装在 AnyView 中会对 SwiftUI 隐藏其类型,削弱 SwiftUI 高效执行差异计算的能力。在可能的情况下,请改用具体类型或 @ViewBuilder。

// Prefer @ViewBuilder over returning AnyView
@ViewBuilder
func content() -> some View {
    if flag { A() } else { B() }
}

稳定标识等于稳定状态

经验法则是:如果希望保留状态并维持平滑动画,就应保持标识稳定;只有确实需要全新开始时,才应有意更改标识。

快速检查:视图标识

请测试您对视图标识的理解。

回顾:理解视图标识

SwiftUI 会以结构方式(树中的位置)和显式方式(.id)标识视图。稳定的标识可以保留 @State,并启用平滑的属性动画;更改标识会重置状态并触发过渡。

请为 ForEach 提供稳定标识,避免对可变数据使用索引标识,尽量减少会切换标识的分支,并在具体类型可行时避免使用 AnyView。

常见问题解答

「理解视图身份」课时是免费的吗?

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

「理解视图身份」这节课中我会学到什么?

控制 SwiftUI 如何比较和复用视图。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

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

「理解视图身份」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 理解视图身份
  2. 减少主体重新求值
  3. Equatable 视图与 @State 作用域
  4. 使用 SwiftUI Instrument 进行性能分析
← 返回 Swift Academy