【问题标题】:SwiftUI Button Action like Android ACTION_DOWN and ACTION_UPSwiftUI 按钮操作,如 Android ACTION_DOWN 和 ACTION_UP
【发布时间】:2020-06-19 03:31:31
【问题描述】:

我正在创建一个 iOS 版本的 Android 应用程序,我需要创建一个按钮,在用户第一次按下时执行一项任务,然后在用户停止按下按钮时执行一项任务。在 Java 中,我使用以下代码完成此操作:

someButton.setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      // Do first task
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
      // Do second task
    }
    return true;
  }
});

我将如何使用 SwiftUI 按钮执行此操作?我发现this answer 告诉了如何获得 ACTION_DOWN 行为,但我不确定这种方法是否有效,因为我需要同时拥有 ACTION_UP 和 ACTION_DOWN。

【问题讨论】:

    标签: android ios swift swiftui


    【解决方案1】:

    这是作为视图修饰符的替代(更可靠)解决方案,因此可以附加到任何不通过状态更新影响其他视图的视图。

    使用 Xcode 11.4 / iOS 13.4 测试。

    struct DemoTouchesHandling: View {
    
        var body: some View {
            VStack {
                Text("Tap Me!").font(Font.system(size: 24).bold().smallCaps())
            }
            .frame(width: 200, height: 200)
            .background(Color.red)
            .modifier(TouchUpDownHandler(downAction: {print("> Down")}, 
                                         upAction: {print("< Up")}))
        }
    }
    
    struct TouchUpDownHandler: ViewModifier {
        var downAction: (() -> Void)?
        var upAction: (() -> Void)?
    
        enum TouchState {
            case inactive
            case down
        }
        @GestureState private var gestureState: TouchState = .inactive // initial & reset value
    
        func body(content: Content) -> some View {
            content
            .gesture(DragGesture(minimumDistance: 0)
                .updating($gestureState, body: { (value, state, transaction) in
                    switch state {
                        case .inactive:
                            state = .down
                            self.downAction?()
                        case .down: break
                    }
                })
                .onEnded { value in
                    self.upAction?()
                }
            )
        }
    }
    

    【讨论】:

    • @BeauForest,是的,但为此,您不需要像原始问题中的onTouch 这样的处理程序,而是直接使用gestureState。这实际上是一个不同的问题。
    • 好的,看来我应该更具体的原始问题。我需要在操作向下和向上操作时执行的任务是状态变量的更新,我没有意识到更新状态变量会导致视图更新并因此导致未定义的行为。我会研究一下gestureState,谢谢。
    【解决方案2】:

    您可以使用 DragGesture

       struct ContentView: View {
         @State private var index = 0
        var body: some View {
            let gesture = DragGesture(minimumDistance: 0, coordinateSpace: .local).onChanged({
                if self.index == 0 {
                    print("Down: \($0)")
                     self.index = 1
                }
            }).onEnded({
    
                if self.index == 1 {
                  print("Up: \($0)")
                     self.index = 0
                }
            })
            return Rectangle().frame(width: 120, height: 60).gesture(gesture)
        }
    }
    

    【讨论】:

    • 如果你在触摸后拖动,你会得到很多“Down:”打印输出,所以 PO 会得到很多 ACTION_DOWN 和 ACTION_UP 动作,这不是我想的那样。
    • 感谢您指出我的错误@Asperi 我只是更新我的答案
    猜你喜欢
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多