【问题标题】:Is there any way to create a new Gesture in SwiftUI?有没有办法在 SwiftUI 中创建一个新的手势?
【发布时间】:2020-09-27 14:15:22
【问题描述】:

SwiftUI 缺少​​平移手势(即缩放和偏移),所以我试图创建一个。但是,Gesture 结构似乎依赖于私有类。例如:

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
    }

}

此代码无法完成,因为 _GraphValue、_GestureInputs 和 _GestureOutputs 是私有的。在我完全放弃之前,我想看看是否有人找到了解决方法。

【问题讨论】:

  • 你有没有运气解决这个问题?我也想创建一个新的手势。
  • 不-抱歉。目前看来没有办法做到这一点。为了这个特殊的需要,我最终创建了一个全新的 ScrollView...☹️

标签: ios swift swiftui uikit


【解决方案1】:

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>
}

这里的困难是约束Self.Value === Self.Body.Value。这意味着您的手势body 不能被声明为返回some Gesture,因为some Gesture 不能满足约束(即使它的Value 会匹配)。所以你必须给body一个特定的类型。最简单的解决方案是使用AnyGesture 类型的橡皮擦:

public struct PinchGesture: Gesture {

    ...

    public var body: AnyGesture<PinchGestureValue> {
        AnyGesture(
            DragGesture(minimumDistance: 0, coordinateSpace: .global)
               .map { PinchGestureValue($0) }
        )
    }
}

在这段代码中,Swift 可以推断出PinchGesture.Value = PinchGestureValuePinchGesture.Body = AnyGesture&lt;PinchGestureValue&gt;。那么它可以证明AnyGesture&lt;PinchGestureValue&gt;.Value == PinchGesture.Value,所以它可以使用SwiftUI提供的_makeGesture的默认实现。

不幸的是,我怀疑你可以用它来创建你的PinchGesture。最终,您的 body 仍然仅限于组合 SwiftUI 的原始手势,这无法让您访问当前的 UIEventUITouch 对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多