Действие кнопки SwiftUI, например Android ACTION_DOWN и ACTION_UP - PullRequest
1 голос
/ 19 июня 2020

Я создаю 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? Я нашел этот ответ , в котором рассказывается, как получить поведение ACTION_DOWN, но я не уверен, что этот подход сработает, поскольку мне нужны как ACTION_UP, так и ACTION_DOWN.

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Вот альтернативное (более надежное) решение в качестве модификатора представления, поэтому его можно прикрепить к любому представлению, не влияющему на другие, обновлением состояния.

Протестировано с 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?()
            }
        )
    }
}
0 голосов
/ 19 июня 2020

Вы можете использовать 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)
    }
}
...