Implement pinch gesture on a SwiftUI's scrollable LazyVGrid

Good day!

Question

How can we implement pinch gesture in SwiftUI and solve the gesture limitation from MagnificationGesture

Description

I'm trying to implement a pinch gesture recognizer on a scrollable LazyVGrid in a SwiftUI-based application, however the pinch gesture has usually been intercepted by the scroll gesture and makes it significantly harder to trigger than using UIKit's UIPinchGestureRecognizer. Here're my findings after a few tests.

  • MagnificationGesture: can detect the pinch gesture when two fingers are dragging at the same time.

  • UIPinchGestureRecognizer: can detect the pinch gesture when two fingers are touching and at least one finger is dragging.

Cases tried

  1. ScrollView + LazyVGrid + MagnificationGesture

Result: difficult to trigger as described

ScrollView {
    LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3)) {
        ForEach(aryItems) { item in
            Text(item.photoId)
                .border(Color.black, width: 1)
        }
    }
}
    .highPriorityGesture(MagnificationGesture()
        .onChanged { value in
            print("test: \(value)")
        })
  1. ScrollView + LazyVGrid + .overlay() + UIPinchGestureRecognizer

Result: the pinch gesture is good, but the overlay blocked all gestures to the cells (eg. tap, force-tap)

ScrollView {
    LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3)) {
        ForEach(aryItems) { item in
            Text(item.photoId)
                .border(Color.black, width: 1)
        }
    }
        .overlay (
            GeometryReader{ proxy in
                ZoomGesture(size: proxy.size, 
                onPinchUpdate: { scale, _ in
                    print("update pinch")
                })
            }
        )
}

struct ZoomGesture: UIViewRepresentable {
    var size: CGSize

    var onPinchUpdate:((_ scale:CGFloat, _ position:CGPoint)->())? = { _,_ in }

    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    func makeUIView(context: Context) -> UIView {
        
        let view = UIView()
        view.backgroundColor = .clear
        
        let Pinchgesture = UIPinchGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handlePinch(sender:)))

        view.addGestureRecognizer(Pinchgesture)
        
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) { }

    fileprivate class Coordinator: NSObject {
        var parent: ZoomGesture

        init(parent: ZoomGesture) {
            self.parent = parent
        }

        @objc
        func handlePinch(sender: UIPinchGestureRecognizer){
            let scalePosition: CGPoint = .zero // temp
            parent.onPinchUpdate?(sender.scale, scalePosition)
        }

    }
}

Thank you for your time!

Did you find a solution? i'm stuck in the same problem

Implement pinch gesture on a SwiftUI's scrollable LazyVGrid
 
 
Q