计算 DragGesture 的速度

lan*_*gio 5 ios swift swiftui

我想提取 DragGesture 的速度以用于弹簧动画的 initialVelocity 参数。我正在尝试创建一个具有响应式弹簧动画的可移动卡片,就像在 Apple Maps 应用程序中找到的那样。

我尝试通过将拖动平移的高度除以拖动手势的总时间来计算速度。

v_abs = abs(Double(drag.translation.height / CGFloat(drag.time.timeIntervalSinceNow)))
Run Code Online (Sandbox Code Playgroud)

问题在于,当用户开始拖动时,他们可能会在轻弹和释放之前减慢拖动速度,这会导致速度非常慢,因为经过了很长时间。如果可能,我只想使用拖动手势最后几毫秒的数据来计算速度。

dba*_*art 15

predictedEndLocation您可以简单地通过使用已提供的来计算隐含速度,而无需保持中间状态DragGesture.Value

DragGesture()
.onChanged { value in 
    // Do something
}
.onEnded { value in
    let velocity = CGSize(
        width:  value.predictedEndLocation.x - value.location.x,
        height: value.predictedEndLocation.y - value.location.y
    )

    // Example

    if velocity.height > 500.0 {
        // Moving down fast
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ard 8

通过将最后一个拖动位置存储为状态,然后在 onEnded 被调用时使用它来导出速度值,我已经能够获得相当不错的拖动速度值。

struct MyComponent: View {

    @State var lastDragPosition: DragGesture.Value?

    var body: some View {
        VStack{
            SomeOtherView()
        }.gesture(
            DragGesture().onChanged { value in
                self.lastDragPosition = value
            }
            .onEnded { value in
                let timeDiff = value.time.timeIntervalSince(self.lastDragPosition!.time)
                let speed:CGFloat = CGFloat(value.translation.height - self.lastDragPosition!.translation.height) / CGFloat(timeDiff)

                if(speed > 500) {
                    //Do Something
                }
            }
        )
    }
}
Run Code Online (Sandbox Code Playgroud)