理解视图身份
控制 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 tabForEach 中的标识
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 identitiesAnyView 会抹除标识信息
将视图包装在 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 反馈 — 无需本地设置。