I'm trying to combine a RotateGesture
and a MagnifyGesture
within a single SwiftUI view using SimultaneousGesture
. My goal is to allow users to rotate and zoom an image (potentially at the same time). However, I’m running into a problem:
If only one gesture (say, the magnification) starts and finishes without triggering the other (rotation), it seems that the rotation gesture is considered "failed." After that, no further .onChanged
or .onEnded
callbacks fire for either gesture until the user lifts their fingers and starts over.
Here’s a simplified version of my code:
struct ImageDragView: View {
@State private var scale: CGFloat = 1.0
@State private var lastScale: CGFloat = 1.0
@State private var angle: Angle = .zero
@State private var lastAngle: Angle = .zero
var body: some View {
Image("Stickers3")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 100)
.rotationEffect(angle, anchor: .center)
.scaleEffect(scale)
.gesture(combinedGesture)
}
var combinedGesture: some Gesture {
SimultaneousGesture(
RotateGesture(minimumAngleDelta: .degrees(8)),
MagnifyGesture()
)
.onChanged { combinedValue in
if let magnification = combinedValue.second?.magnification {
let minScale = 0.2
let maxScale = 5.0
let newScale = magnification * lastScale
scale = max(min(newScale, maxScale), minScale)
}
if let rotation = combinedValue.first?.rotation {
angle = rotation + lastAngle
}
}
.onEnded { _ in
lastScale = scale
lastAngle = angle
}
}
}
-
If I pinch and rotate together (or just rotate), both gestures work as expected.
-
But if I only pinch (or, sometimes, if the rotation amount doesn’t meet
minimumAngleDelta
), subsequent gestures don’t trigger the.onChanged
or.onEnded
callbacks anymore, as if the entire gesture sequence is canceled.
I found that setting minimumAngleDelta: .degrees(0)
helps because then rotation almost never fails. But I’d like to understand why this happens and whether there’s a recommended way to handle the situation where one gesture might be recognized but not the other, without losing the gesture recognition session entirely.
Is there a known workaround or best practice for combining a pinch and rotate gesture where either one might occur independently, but we still want both gestures to remain active?
Any insights would be much appreciated!