Как лучше всего получить скорость перетаскивания?
Мне было интересно, как можно получить DragGesture
Скорость?
Я понимаю, что формула работает и как получить ее вручную, но когда я это делаю, Apple не возвращает то, что возвращает (по крайней мере, иногда это совсем другое).
У меня есть следующий фрагмент кода
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
но, к сожалению, у меня нет возможности получить к нему доступ (по крайней мере, я не знаю), поэтому я должен вычислить его сам, теоретически мои расчеты верны, но они сильно отличаются от Apple. Так в чем проблема?
2 ответа
Это еще один подход к извлечению скорости из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)")
}
}
Именно так:
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!)!)