在 SwiftUI 中,@GestureState 是一种用于管理手势状态的属性包装器。它的核心作用是用来跟踪手势的临时状态,并在手势结束时自动重置其值。@GestureState 专为处理手势的动态变化而设计,是手势驱动交互中非常有用的工具。
@GestureState 的核心特性
1、临时状态:手势进行过程中,@GestureState 的值会根据手势的状态动态更新。
2、自动重置:手势结束后,SwiftUI 会自动将其值重置为初始值(在定义时指定的默认值)。
3、轻量且无副作用:它不会引起视图的重绘(不像 @State 或 @Binding 那样会强制刷新视图)。
基本用法
以下是一个用 @GestureState 实现拖动手势的简单示例:
示例代码
import SwiftUI
struct GestureStateExample: View {
@GestureState private var dragOffset: CGSize = .zero
var body: some View {
Circle()
.fill(Color.blue)
.frame(width: 100, height: 100)
.offset(dragOffset) // 根据手势动态偏移
.gesture(
DragGesture()
.updating($dragOffset) { value, state, _ in
state = value.translation // 动态更新手势状态
}
)
}
}

代码解析
1、@GestureState private var dragOffset: CGSize = .zero
定义一个手势状态变量,用于存储拖动手势的偏移量,初始值为 .zero。
2、.gesture(DragGesture().updating($dragOffset))
DragGesture 是一个拖动手势,.updating 用于在手势变化时更新 @GestureState。
state 是 @GestureState 绑定的临时状态值。
value.translation 表示拖动手势的偏移量。
3、自动重置
当拖动手势结束时,dragOffset 会自动重置为 .zero,无需手动处理。
与 @State 的区别
@GestureState
临时状态,仅在手势活动时有效。
手势结束后自动重置。
不会触发视图的刷新。
@State
持久状态,保留其值直到显式更改。
任何更改都会触发视图刷新。
高级用法示例
实现动态缩放手势
使用 @GestureState 来实现一个缩放手势:
struct GestureStateScaleExample: View {
@GestureState private var scale: CGFloat = 1.0
var body: some View {
Circle()
.fill(Color.green)
.frame(width: 100, height: 100)
.scaleEffect(scale) // 根据手势动态缩放
.gesture(
MagnificationGesture()
.updating($scale) { value, state, _ in
state = value // 更新缩放比例
}
)
}
}

组合手势示例
可以使用 @GestureState 和 DragGesture 配合,实现同时拖动和缩放的效果:
struct CombinedGestureExample: View {
@GestureState private var dragOffset: CGSize = .zero
@GestureState private var scale: CGFloat = 1.0
var body: some View {
Circle()
.fill(Color.orange)
.frame(width: 100, height: 100)
.offset(dragOffset) // 拖动偏移
.scaleEffect(scale) // 缩放效果
.gesture(
SimultaneousGesture(
DragGesture().updating($dragOffset) { value, state, _ in
state = value.translation // 更新拖动偏移
},
MagnificationGesture().updating($scale) { value, state, _ in
state = value // 更新缩放比例
}
)
)
}
}

使用场景
1、手势跟踪:实时跟踪手势状态,比如拖动、缩放、旋转等。
2、临时状态管理:不需要在手势结束后保留状态时,@GestureState 是理想选择。
3、轻量级交互:通过动态更新手势状态而不引起视图重绘,提升性能。
总结
@GestureState 是 SwiftUI 手势系统中非常强大的工具,适用于实现临时状态管理和动态交互。它的临时性和自动重置特性让它在手势驱动的 UI 设计中非常方便。