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'sbodycan't be declared to returnsome Gesture, becausesome Gesturecan't satisfy the constraint (even if itsValuewould match). So you have to givebodya specific type. The easiest solution is to use theAnyGesturetype eraser:In this code, Swift can infer
PinchGesture.Value = PinchGestureValueandPinchGesture.Body = AnyGesture<PinchGestureValue>. Then it can proveAnyGesture<PinchGestureValue>.Value == PinchGesture.Value, so it can use the default implementation of_makeGestureprovided by SwiftUI.Unfortunately, I doubt you can use this to create your
PinchGesture. Ultimately, yourbodyis still restricted to combining SwiftUI's primitive gestures, which don't give you access the currentUIEventorUITouchobjects.