Swiftui 通过ObserveObject向下传递GestureState属性

Swiftui 通过ObserveObject向下传递GestureState属性,swiftui,Swiftui,我有一个observeObject,它有一个带有@GestureState包装器的成员属性。在我看来,如何访问GestureState属性 我已经尝试过在$绑定中使用点表示法来公开GestureState,但它不喜欢这样 我的AppState可观察对象: class AppState:ObservableObject{ let objectWillChange=observeObjectPublisher() @GestureState变量currentState:LongPressState=

我有一个
observeObject
,它有一个带有
@GestureState
包装器的成员属性。在我看来,如何访问
GestureState
属性

我已经尝试过在
$
绑定中使用点表示法来公开GestureState,但它不喜欢这样

我的AppState
可观察对象

class AppState:ObservableObject{
let objectWillChange=observeObjectPublisher()
@GestureState变量currentState:LongPressState=.inactive
公共枚举LongPressState:字符串{
case inactive=“inactive”
case pressing=“pressing”
案例控股=“控股”
}
}
我的代码中对象的实现:

@ObservedObject变量appState:appState
.
.
.
让长按=长按手势(最小持续时间:最小长按持续时间)
.已排序(之前:长按手势(最短持续时间:5))
.正在更新(appState.$currentState){中的值、状态、事务
开关量{
第一种情况(正确):
状态=.pressing
第二种情况(对,错):
状态=.holding
违约:
状态=.inactive
}
}

我实际上没有在这个视图中得到任何构建时错误,但是它使层次结构更高的视图无效。如果我将
@ObservedObject
替换为本地
@GestureState
属性,则它可以正常工作。

我找到了一种非常有效的解决方法

想法很简单:你有两次你的
currentState

  • 在视图中作为
    GestureState
  • 在您的
    可观察对象中
    类作为
    已发布
  • 这是必要的,因为
    GestureState
    只能在视图中声明。现在唯一要做的就是以某种方式同步它们

    这里有一个可能的解决方案:(使用
    onChange(of:)

    注 我发现动画有点像马车。向手势添加一个
    oneded
    ,修复了它(DragGesture)

    class AppState: ObservableObject {
    
        @Published var currentState: LongPressState = .inactive
        
        enum LongPressState: String { ... }
        ...
    }
    
    struct ContentView: View {
    
        @StateObject private var appState = AppState()
        @GestureState private var currentState: AppState.LongPressState = .inactive
    
         
        var body: some View {
            SomeView() 
                .gesture(
                     LongPressGesture() 
                         .updating($currentState) { value, state, transaction in
                             ...
                         }
                )
                .onChange(of: currentState) { appState.currentState = $0 } 
        }
    }
    
    .onEnded { 
       appState.currentState = .inactive //if you are using DragGesture: .zero (just set to it's initial state again)
    }