使用 matchedGeometryEffect 实现英雄转场
结合命名空间和匹配 ID,在视图之间创建无缝的英雄动画。
使用 matchedGeometryEffect 实现英雄转场 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
什么是 matchedGeometryEffect?
matchedGeometryEffect 会在两个状态之间为视图的位置和大小添加动画,从而创建“英雄式”转场。
struct HeroDemo: View {
@Namespace private var ns
@State private var expanded = false
var body: some View {
if expanded {
BigCard().matchedGeometryEffect(id: "card", in: ns)
} else {
SmallCard().matchedGeometryEffect(id: "card", in: ns)
}
}
}创建 Namespace
在父视图中声明一个 @Namespace。所有匹配的视图共享此命名空间。
struct ParentView: View {
@Namespace private var heroNamespace
}应用修饰器
对源视图和目标视图都使用 .matchedGeometryEffect(id:in:),并传入相同的 id。
Image("cover")
.matchedGeometryEffect(id: "albumArt", in: heroNamespace)触发转场
将状态变化包裹在 withAnimation 中,以便在两个视图之间为几何属性添加动画。
Button("Expand") {
withAnimation(.spring()) {
isExpanded.toggle()
}
}从列表到详情的英雄转场
一种经典的英雄转场模式:点按列表项后,使用 matchedGeometryEffect 将其展开为全屏详情页。
ForEach(items) { item in
ThumbnailRow(item: item)
.matchedGeometryEffect(id: item.id, in: ns)
.onTapGesture { withAnimation { selected = item } }
}
if let sel = selected {
DetailView(item: sel)
.matchedGeometryEffect(id: sel.id, in: ns)
}isSource 参数
当两个视图共享同一个 id 时,将源视图标记为 isSource: true(默认值),将目标视图标记为 isSource: false。
SmallImage()
.matchedGeometryEffect(id: "img", in: ns, isSource: true)
LargeImage()
.matchedGeometryEffect(id: "img", in: ns, isSource: false)锚点和大小属性
您可以自定义要匹配的锚点,以及要匹配的几何属性(位置/大小)。
.matchedGeometryEffect(
id: "box",
in: ns,
anchor: .center,
properties: [.position, .size]
)与 AnyTransition 组合
将英雄动画与 .transition 组合使用,还可以控制内容淡入或滑入的方式。
DetailView()
.matchedGeometryEffect(id: "card", in: ns)
.transition(.opacity)列表中的多个英雄转场
使用从项目标识符派生的唯一 ID,即可运行多个相互独立的英雄动画。
ForEach(products) { p in
ProductCard(p)
.matchedGeometryEffect(id: p.id, in: ns)
}常见问题
具有相同 ID 的两个视图不能同时出现——任意时刻只能显示其中一个,否则会出现布局异常。
// Wrong: both views visible at same time
Small().matchedGeometryEffect(id: "x", in: ns)
Large().matchedGeometryEffect(id: "x", in: ns)
// Correct: use if/else or ZStack with opacity toggling性能提示
请保持匹配视图的结构轻量。匹配视图内部的层级过于复杂,可能会导致动画过程中丢帧。
// Prefer simple shapes inside matched containers
// Move heavy content outside the matched frame快速检查
要在英雄转场中将两个视图关联为源视图和目标视图,需要什么条件?
课程回顾
使用 @Namespace 和 .matchedGeometryEffect(id:in:) 创建英雄转场。将状态变化包裹在 withAnimation 中。确保同一时刻只显示一个匹配视图,以避免布局冲突。
常见问题解答
「使用 matchedGeometryEffect 实现英雄转场」课时是免费的吗?
是的 — 「使用 matchedGeometryEffect 实现英雄转场」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「使用 matchedGeometryEffect 实现英雄转场」这节课中我会学到什么?
结合命名空间和匹配 ID,在视图之间创建无缝的英雄动画。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 matchedGeometryEffect 实现英雄转场」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 隐式动画与显式动画
- 使用 matchedGeometryEffect 实现英雄转场
- 自定义 AnimatableModifier 与 Animatable
- TimelineView 与 Canvas 高性能绘制