I am trying to achieve drag and magnification gestures take in place simultaneously. With the code below, I was able to achieve transitioning dragging to magnifying, however, when I release one finger after magnification, the drag gesture is killed even though one finger is still on the rectangle. In the Photos app in iOS, you can magnify and release one finger then you can still drag an image. I have looked at Simultaneous MagnificationGesture and DragGesture with SwiftUI. Has this been fixed since then? If not, is there any way to achieve this by using UIViewRepresentable?

import SwiftUI

struct DragAndMagnificationGestures: View {
    @State private var currentAmount = 0.0
    @State private var finalAmount = 1.0
    @State private var dragGestureOffset: CGSize = .zero

    var body: some View {
        VStack {
            let combined = dragGesture.simultaneously(with: magnificationGesture)
            
            Rectangle()
                .frame(width: 200, height: 200)
                .scaleEffect(finalAmount + currentAmount)
                .offset(dragGestureOffset)
                .gesture(combined)
        }
    }
}

struct MultiGesture_Previews: PreviewProvider {
    static var previews: some View {
        DragAndMagnificationGestures()
    }
}

extension DragAndMagnificationGestures {
    private var dragGesture: some Gesture {
        DragGesture()
            .onChanged { value in
                if finalAmount != 0 {
                    withAnimation(.spring()) {
                        dragGestureOffset = value.translation
                    }
                }
            }
            .onEnded({ value in
                withAnimation(.spring()) {
                    dragGestureOffset = .zero
                }
            })
    }
    
    private var magnificationGesture: some Gesture {
        MagnificationGesture()
            .onChanged { amount in
                currentAmount = amount - 1
            }
            .onEnded({ amount in
                finalAmount += currentAmount
                currentAmount = 0
            })
    }
}
0

There are 0 best solutions below