通过 ObservableObject 向下传递 GestureState 属性

pal*_*att 6 swiftui

我有一个ObservableObject带有@GestureState包装器的成员属性。在我看来,我如何才能访问该GestureState房产?

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

我的应用程序状态ObservableObject

class AppState: ObservableObject {
    let objectWillChange = ObservableObjectPublisher()

    @GestureState var currentState: LongPressState = .inactive

    public enum LongPressState: String {
        case inactive = "inactive"
        case pressing = "pressing"
        case holding = "holding"
    }
}
Run Code Online (Sandbox Code Playgroud)

我的代码中对象的实现:

@ObservedObject var appState: AppState
.
.
.
let longPress = LongPressGesture(minimumDuration: minLongPressDuration)
   .sequenced(before: LongPressGesture(minimumDuration: 5))
   .updating(appState.$currentState) { value, state, transaction in
      switch value {
      case .first(true):
         state = .pressing
      case .second(true, false):
         state = .holding
      default:
         state = .inactive
      }
}
Run Code Online (Sandbox Code Playgroud)

实际上,我在此视图中没有收到任何构建时错误,但它使层次结构中较高的视图无效。如果我@ObservedObject用本地@GestureState属性替换它,那么它就可以正常工作。

Mof*_*waw 5

我找到了一个完美的解决方法。

这个想法很简单:你有currentState两次。

  1. 在你的观点中GestureState
  2. 在你的ObservableObject班级中作为Published

这是必要的,因为GestureState只能在视图中声明。现在唯一要做的就是以某种方式同步它们。

这是一种可能的解决方案:(使用onChange(of:)

class AppState: ObservableObject {

    @Published var currentState: LongPressState = .inactive
    
    enum LongPressState: String { ... }
    ...
}
Run Code Online (Sandbox Code Playgroud)
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 } 
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记

我发现动画有点问题。添加onEnded到手势修复了它(DragGesture)。

.onEnded { 
   appState.currentState = .inactive //if you are using DragGesture: .zero (just set to it's initial state again)
}
Run Code Online (Sandbox Code Playgroud)