[英]Is there any way to create a new Gesture in SwiftUI?
SwiftUI is missing a Pan gesture (that is, both scale and offset), so I was trying to create one. SwiftUI 缺少平移手势(即缩放和偏移),所以我试图创建一个。 However, it appears that the Gesture struct depends on private classes.
但是,似乎 Gesture 结构依赖于私有类。 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.此代码无法完成,因为 _GraphValue、_GestureInputs 和 _GestureOutputs 是私有的。 Before I give in completely, I wanted to see if anyone has figured out a workaround.
在我完全屈服之前,我想看看是否有人找到了解决方法。
SwiftUI provides a default implementation of _makeGesture
: SwiftUI提供的默认实现
_makeGesture
:
extension Gesture where Self.Value == Self.Body.Value {
public static func _makeGesture(gesture: SwiftUI._GraphValue<Self>, inputs: SwiftUI._GestureInputs) -> SwiftUI._GestureOutputs<Self.Body.Value>
}
The difficulty here is the constraint Self.Value === Self.Body.Value
.这里的困难是约束
Self.Value === Self.Body.Value
。 That means your gesture's body
can't be declared to return some Gesture
, because some Gesture
can't satisfy the constraint (even if its Value
would match).这意味着你的手势
body
不能被声明为返回some Gesture
,因为some Gesture
不能满足约束(即使它的Value
匹配)。 So you have to give body
a specific type.所以你必须给
body
一个特定的类型。 The easiest solution is to use the AnyGesture
type eraser:最简单的解决方案是使用
AnyGesture
类型的橡皮擦:
public struct PinchGesture: Gesture {
...
public var body: AnyGesture<PinchGestureValue> {
AnyGesture(
DragGesture(minimumDistance: 0, coordinateSpace: .global)
.map { PinchGestureValue($0) }
)
}
}
In this code, Swift can infer PinchGesture.Value = PinchGestureValue
and PinchGesture.Body = AnyGesture<PinchGestureValue>
.在这段代码中,Swift 可以推断出
PinchGesture.Value = PinchGestureValue
和PinchGesture.Body = AnyGesture<PinchGestureValue>
。 Then it can prove AnyGesture<PinchGestureValue>.Value == PinchGesture.Value
, so it can use the default implementation of _makeGesture
provided by SwiftUI.然后它可以证明
AnyGesture<PinchGestureValue>.Value == PinchGesture.Value
,所以它可以使用_makeGesture
提供的 _makeGesture 的默认实现。
Unfortunately, I doubt you can use this to create your PinchGesture
.不幸的是,我怀疑您是否可以使用它来创建您的
PinchGesture
。 Ultimately, your body
is still restricted to combining SwiftUI's primitive gestures, which don't give you access the current UIEvent
or UITouch
objects.最终,您的
body
仍然仅限于组合 SwiftUI 的原始手势,这不会让您访问当前的UIEvent
或UITouch
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.