在 SwiftUI 中,转场(Transition) 和 变形(Transform) 是两种不同的动画效果机制,它们的核心区别在于 应用场景 和 控制方式。以下是详细对比:
1. 转场(Transition)
定义
控制 视图的插入或移除 时的动画效果(如出现、消失、切换)。
-
适用场景 :
- 视图条件渲染(
if
/else
、ForEach
动态增减)。 - 导航跳转(
NavigationView
或NavigationStack
的页面切换)。
- 视图条件渲染(
-
常见类型 :
swift.transition(.opacity) // 淡入淡出(默认) .transition(.slide) // 滑入滑出 .transition(.scale) // 缩放 .transition(.asymmetric(insertion: .move(edge: .leading), removal: .opacity)) // 不对称转场
特点
- 需配合
withAnimation
或视图容器(如ZStack
/List
)使用。 - 默认无动画:必须显式指定转场类型才会生效。
- 与
onAppear
/onDisappear
生命周期关联。
示例代码:
swift
struct TransitionDemo: View {
@State private var show = false
var body: some View {
VStack {
if show {
Text("Hello!")
.transition(.slide) // 滑入滑出
}
Button("Toggle") {
withAnimation {
show.toggle() // 触发转场动画
}
}
}
}
}
2. 变形(Transform)
定义
通过 几何变换(如平移、旋转、缩放)修改视图的显示形态,通常使用以下修饰符:
.offset(x:y:)
:平移。.rotationEffect(_:)
:旋转。.scaleEffect(_:)
:缩放。.transformEffect(_:)
:自定义 2D 仿射变换(CGAffineTransform
)。
适用场景
- 视图的 持续状态变化(如拖动、动态缩放)。
- 非结构化的视觉调整(如按钮悬停效果)。
示例代码:
swift
struct TransformDemo: View {
@State private var scale: CGFloat = 1.0
var body: some View {
Button("点击放大") {
withAnimation(.spring()) {
scale += 0.5 // 触发缩放动画
}
}
.scaleEffect(scale)
.rotationEffect(.degrees(scale > 1 ? 45 : 0)) // 条件旋转
}
}
3. 核心区别总结
特性 | 转场(Transition) | 变形(Transform) |
---|---|---|
作用目标 | 视图的插入或移除 | 视图的几何形态变化 |
动画触发条件 | 视图树结构变化(如 if 条件) |
视图属性变化(如 @State 数值) |
默认行为 | 无动画(需显式指定) | 部分属性默认有动画(如 .offset ) |
常见修饰符 | .transition(_:) |
.scaleEffect /.rotationEffect |
控制粒度 | 整体视图的进入/退出效果 | 视图的局部形变 |
4. 如何选择?
-
用转场(Transition):
- 需要控制视图 出现或消失 的动画(如列表项的删除、模态弹窗的展示)。
- 配合
ZStack
或条件语句使用。
-
用变形(Transform):
- 需要动态调整视图的 位置、大小、角度(如拖动卡片、按钮点击效果)。
- 直接修改视图的几何属性。
5. 组合使用示例
转场和变形可以协同工作,创造复杂效果:
swift
struct CombinedDemo: View {
@State private var show = false
var body: some View {
VStack {
if show {
Text("组合效果")
.transition(.opacity.combined(with: .scale)) // 转场:淡入 + 缩放
.scaleEffect(2.0) // 变形:额外放大
}
Button("Toggle") {
withAnimation(.easeInOut(duration: 1.0)) {
show.toggle()
}
}
}
}
}
6. 注意事项
-
转场必须配合动画:
swift// 错误:缺少 withAnimation,转场不会生效 if show { Text("Hi") .transition(.slide) } // 正确 withAnimation { show.toggle() }
-
变形可能影响布局 :
.offset
或.scaleEffect
不会改变视图的原始布局占位(需用.frame
调整)。 -
性能优化 :
避免对大量视图同时应用复杂转场或变形,可能影响渲染性能。
总结
- 转场 = 视图的"生与死"动画(结构变化)。
- 变形 = 视图的"外貌"动画(属性变化)。
- 灵活组合两者,可以构建更丰富的交互体验!