4

我遵循了有关如何使用 UIViewPropertyAnimator 创建交互式 iOS 控制中心动画的教程:

http://www.swiftkickmobile.com/building-better-app-animations-swift-uiviewpropertyanimator/

向上或向下滑动底部菜单时,松开手指后,我想添加平移速度UIViewPropertyAnimator并继续动画:

popupViewPanned(recognizer:) {

    switch recognizer.state {
        .
        .
        .
    // after finger released
        case .end:
        // continue all animations using pan velocity with spring timing

        let normalizedPanVelocity: // how to normalize pan velocity
     runningAnimators.forEach { $0.continueAnimation(withTimingParameters: spring(for: velocity()), durationFactor: 0) }
    }
}

func velocity() -> CGVector {
    let pan = panRecognizer
    let progress = runningAnimators[0].fractionComplete
    let fraction = popupOffset*(1 - progress)
    return CGVector(with: pan.velocity(in: view), fraction: fraction)
}
func spring(for velocity: CGVector = .zero) -> UITimingCurveProvider {
    return UISpringTimingParameters(dampingRatio: 0.9, initialVelocity: velocity)//UISpringTimingParameters(mass: 2.5, stiffness: 80, damping: 25, initialVelocity: velocity)
}

问题是当我快速向上或向下滑动菜单并释放更精细时,动画似乎撞到了墙上(快慢),然后继续休息

那么我该如何解决这个问题?我已经尝试了一整天,但我无法修复它

4

1 回答 1

4

文档UISpringTimingParameters说: https ://developer.apple.com/documentation/uikit/uispringtimingparameters/1649832-init

一个大小为 1.0 的向量对应于一个初始速度,该速度将在一秒内覆盖整个动画距离。例如,如果总动画距离为 200 点,并且视图的初始速度为每秒 100 点,则指定幅度为 0.5 的向量。

这意味着您必须使用视图的 with 来标准化速度。

CGVector并且查看您正在使用的初始化程序 的官方文档,令人困惑的是没有记录。https://developer.apple.com/documentation/coregraphics/cgvector

我最终做的是自己计算归一化向量。您需要计算视图从动画开始到结束移动的总点数,然后使用它distanceToMove从中制作“单位向量”/对其进行规范化:

let distanceToMove = newY - oldY
let velocity = recognizer.velocity(in: view)
let relativeVelocityY = velocity.x / distanceToMove
let relativeVelocity = CGVector(dx: 0, dy: relativeVelocityY)
let timing = UISpringTimingParameters(dampingRatio: 0.9, initialVelocity: relativeVelocity)

让我知道这是否对您有用。

于 2018-09-29T18:15:27.017 回答