获得阻力速度的最佳方法是什么?

问题描述 投票:0回答:2

我想知道如何获得

DragGesture
速度?

我了解公式的工作原理以及如何手动获取它,但当我这样做时,苹果返回的并不是(至少有时它非常不同)。

我有以下代码片段

struct SecondView: View {
    @State private var lastValue: DragGesture.Value?

    private var dragGesture: some Gesture {
        DragGesture()
             .onChanged { (value) in
                   self.lastValue = value
             }
             .onEnded { (value) in
                   if lastValue = self.lastValue {
                         let timeDiff = value.time.timeIntervalSince(lastValue.time)
                         print("Actual \(value)")   // <- A
                         print("Calculated: \((value.translation.height - lastValue.translation.height)/timeDiff)") // <- B
                   }
             }

     var body: some View {
          Color.red
              .frame(width: 50, height: 50)
              .gesture(self.dragGesture)
     }
}

从上面:

A
将输出类似
Value(time: 2001-01-02 16:37:14 +0000, location: (250.0, -111.0), startLocation: (249.66665649414062, 71.0), velocity: SwiftUI._Velocity<__C.CGSize>(valuePerSecond: (163.23212105439427, 71.91841849340494)))

的内容

B
将输出类似
Calculated: 287.6736739736197

的内容

来自

A
的注释我正在查看
valuePerSecond
中的第二个值,即
y velocity

根据您拖动的方式,结果会不同或相同。 Apple 将速度作为属性提供,就像

.startLocation
.endLocation
一样,但不幸的是我无法访问它(至少我不知道)
所以我必须自己计算它,理论上我的计算是正确的但它们与苹果有很大不同。那么这里有什么问题呢?

swiftui gesture draggesture
2个回答
0
投票

最终答案

现在 iOS 17 提供了一个内置的

DragGesture.Value.velocity
属性,并且它似乎一直向后部署到 iOS 13。因此,不再需要使用反射了。

原答案

这是从

DragGesture.Value
中提取速度的另一种方法。它比其他答案中建议的解析调试描述更强大,但仍然有可能中断。

import SwiftUI

extension DragGesture.Value {
    
    /// The current drag velocity.
    ///
    /// While the velocity value is contained in the value, it is not publicly available and we
    /// have to apply tricks to retrieve it. The following code accesses the underlying value via
    /// the `Mirror` type.
    internal var velocity: CGSize {
        let valueMirror = Mirror(reflecting: self)
        for valueChild in valueMirror.children {
            if valueChild.label == "velocity" {
                let velocityMirror = Mirror(reflecting: valueChild.value)
                for velocityChild in velocityMirror.children {
                    if velocityChild.label == "valuePerSecond" {
                        if let velocity = velocityChild.value as? CGSize {
                            return velocity
                        }
                    }
                }
            }
        }
        
        fatalError("Unable to retrieve velocity from \(Self.self)")
    }
    
}

-2
投票

就像这样:

let sss = "\(value)"
//Intercept string
let start = sss.range(of: "valuePerSecond: (")
let end = sss.range(of: ")))")
let arr = String(sss[(start!.upperBound)..<(end!.lowerBound)]).components(separatedBy: ",")
print(Double(arr.first!)!)
© www.soinside.com 2019 - 2024. All rights reserved.