简体   繁体   English

SwiftUI 按钮动作,如 Android ACTION_DOWN 和 ACTION_UP

[英]SwiftUI Button Action like Android ACTION_DOWN and ACTION_UP

I am creating an iOS version of an Android app, and I need to create a button that performs one task when the user first presses down, then one task when the user stops pressing the button.我正在创建 Android 应用程序的 iOS 版本,并且我需要创建一个按钮,在用户第一次按下时执行一项任务,然后在用户停止按下按钮时执行一项任务。 In Java, I did this using the following code:在 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;
  }
});

How would I do this using a SwiftUI Button?我将如何使用 SwiftUI 按钮执行此操作? I found this answer that tells how to get the ACTION_DOWN behavior, but I'm not sure this approach would work since I need to have both the ACTION_UP and ACTION_DOWN.我发现这个答案告诉了如何获得 ACTION_DOWN 行为,但我不确定这种方法是否有效,因为我需要同时拥有 ACTION_UP 和 ACTION_DOWN。

Here is alternate (more reliable) solution as view modifier, so can be attached to any view not affecting others by state update.这是作为视图修饰符的替代(更可靠)解决方案,因此可以通过 state 更新附加到不影响其他视图的任何视图。

Tested with Xcode 11.4 / iOS 13.4.使用 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?()
            }
        )
    }
}

You can use a DragGesture您可以使用 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)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM