How do you detect a SwiftUI touchDown event with no movement or duration?

后端 未结 6 848
无人及你
无人及你 2020-12-19 02:21

I\'m trying to detect when a finger first makes contact with a view in SwiftUI. I could do this very easily with UIKit Events but can\'t figure this out in SwiftUI.

I

6条回答
  •  北荒
    北荒 (楼主)
    2020-12-19 03:05

    If you combine the code from these two questions:

    How to detect a tap gesture location in SwiftUI?

    UITapGestureRecognizer - make it work on touch down, not touch up?

    You can make something like this:

    ZStack {
        Text("Test")
        TapView {
            print("Tapped")
        }
    }
    
    struct TapView: UIViewRepresentable {
        var tappedCallback: (() -> Void)
    
        func makeUIView(context: UIViewRepresentableContext) -> TapView.UIViewType {
            let v = UIView(frame: .zero)
            let gesture = SingleTouchDownGestureRecognizer(target: context.coordinator,
                                                           action: #selector(Coordinator.tapped))
            v.addGestureRecognizer(gesture)
            return v
        }
    
        class Coordinator: NSObject {
            var tappedCallback: (() -> Void)
    
            init(tappedCallback: @escaping (() -> Void)) {
                self.tappedCallback = tappedCallback
            }
    
            @objc func tapped(gesture:UITapGestureRecognizer) {
                self.tappedCallback()
            }
        }
    
        func makeCoordinator() -> TapView.Coordinator {
            return Coordinator(tappedCallback:self.tappedCallback)
        }
    
        func updateUIView(_ uiView: UIView,
                          context: UIViewRepresentableContext) {
        }
    }
    
    class SingleTouchDownGestureRecognizer: UIGestureRecognizer {
        override func touchesBegan(_ touches: Set, with event: UIEvent) {
            if self.state == .possible {
                self.state = .recognized
            }
        }
        override func touchesMoved(_ touches: Set, with event: UIEvent) {
            self.state = .failed
        }
        override func touchesEnded(_ touches: Set, with event: UIEvent) {
            self.state = .failed
        }
    }
    

    There's definitely some abstractions we can make so that the usage is more like the other SwiftUI Gestures, but this is a start. Hopefully Apple builds in support for this at some point.

提交回复
热议问题