SwiftUI is missing a Pan gesture (that is, both scale and offset), so I was trying to create one. However, it appears that the Gesture struct depends on private classes. For example:
public struct PinchGesture: Gesture {
public struct PinchGestureValue: Equatable {
var scale: CGFloat
var anchor: UnitPoint
var offset: CGSize
var isPinching: Bool
}
public typealias Value = PinchGestureValue
public typealias Body = Never
var minimumScaleDelta: CGFloat
var minimumDistance: CGFloat
var coordinateSpace: CoordinateSpace
public init(minimumScaleDelta: CGFloat = 0.01, minimumDistance: CGFloat = 10, coordinateSpace: CoordinateSpace = .local) {
self.minimumScaleDelta = minimumScaleDelta
self.minimumDistance = minimumDistance
self.coordinateSpace = coordinateSpace
}
public static func _makeGesture(gesture: _GraphValue<PinchGesture>, inputs: _GestureInputs) -> _GestureOutputs<PinchGestureValue> {
// Unable to complete
}
}
This code cannot be completed, as the _GraphValue, _GestureInputs, and _GestureOutputs are private. Before I give in completely, I wanted to see if anyone has figured out a workaround.
SwiftUI provides a default implementation of
_makeGesture
:The difficulty here is the constraint
Self.Value === Self.Body.Value
. That means your gesture'sbody
can't be declared to returnsome Gesture
, becausesome Gesture
can't satisfy the constraint (even if itsValue
would match). So you have to givebody
a specific type. The easiest solution is to use theAnyGesture
type eraser:In this code, Swift can infer
PinchGesture.Value = PinchGestureValue
andPinchGesture.Body = AnyGesture<PinchGestureValue>
. Then it can proveAnyGesture<PinchGestureValue>.Value == PinchGesture.Value
, so it can use the default implementation of_makeGesture
provided by SwiftUI.Unfortunately, I doubt you can use this to create your
PinchGesture
. Ultimately, yourbody
is still restricted to combining SwiftUI's primitive gestures, which don't give you access the currentUIEvent
orUITouch
objects.