Tapping once with both hands only works sometimes in visionOS

Hello!

I have an iOS app where I am looking into support for visionOS. I have a whole bunch of gestures set up using UIGestureRecognizer and so far most of them work great in visionOS! But I do see something odd that I am not sure can be fixed on my end. I have a UITapGestureRecognizer which is set up with numberOfTouchesRequired = 2 which I am assuming translates in visionOS to when you tap your thumb and index finger on both hands. When I tap with both hands sometimes this tap gesture gets kicked off and other times it doesn't and it says it only received one touch when it should be two.

Interestingly, I see this behavior in Apple Maps where tapping once with both hands should zoom out the map, which only works sometimes.

Can anyone explain this or am I missing something?

Hi @klinee101 ,

Thanks for bringing this up, I created an app and tested it on-device and was able to see that the two touches does work as expected. However, I only tested it enough to make sure that the two touches is supposed to work, so I of course believe you when you say you've run into situations where it doesn't :)

This sounds like a bug to me, please file a feedback report at https://feedbackassistant.apple.com and post the FB number here so I can make sure it gets routed to the right folks. Thanks!

Sydney

Hello Sydney,

Thank you for the response. I forgot to add that there is a metal view involved in this app and that could be another reason why this problem occurs. I have some simple code here that shows the problem. Can you give this a test? You will notice that the gesture only gets recognized about half the time.

struct ContentView: View {
    var body: some View {
        MetalView()
    }
}

struct MetalView: UIViewRepresentable {
    var device: MTLDevice?

    init() {
        self.device = MTLCreateSystemDefaultDevice()
    }

    func makeUIView(context: Context) -> MTKView {
        let mtkView = MTKView()
        mtkView.device = device
        mtkView.clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
        mtkView.delegate = context.coordinator

        // Add tap gesture recognizer
        let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handleTap(_:)))
        tapGesture.numberOfTapsRequired = 1
        
        // Should require both hands to tap.
        tapGesture.numberOfTouchesRequired = 2
        mtkView.addGestureRecognizer(tapGesture)

        return mtkView
    }

    func updateUIView(_ uiView: MTKView, context: Context) { }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, MTKViewDelegate {
        var parent: MetalView

        init(_ parent: MetalView) {
            self.parent = parent
        }

        func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { }

        func draw(in view: MTKView) {
            guard let drawable = view.currentDrawable else { return }
            guard let descriptor = view.currentRenderPassDescriptor else { return }

            let commandQueue = parent.device?.makeCommandQueue()
            let commandBuffer = commandQueue?.makeCommandBuffer()
            let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor)

            renderEncoder?.endEncoding()
            commandBuffer?.present(drawable)
            commandBuffer?.commit()
        }

        @objc func handleTap(_ sender: UITapGestureRecognizer) {
            print("MTKView tapped")
        }
    }
}

I'm happy to submit a feedback report but I'm curious what your feedback is when you see the issue.

Thank you!

Feedback number -> FB14442495

Hi @klinee101 ,

Thanks so much for all the info + the bug. I tested with and without the metal code and I see it reproducing more than I was previously, which is interesting. There's definitely something going on here!

Thank you for confirming! I look forward to hearing back from either here or the feedback report.

Tapping once with both hands only works sometimes in visionOS
 
 
Q