Добавить скорость UIPanGestureRecognizer в UIViewPropertyAnimator
Я ознакомился с руководством по созданию интерактивной анимации центра управления iOS с помощью UIViewPropertyAnimator:
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)
}
проблема в том, что когда я быстро проведу пальцем вверх или вниз по меню и отпущу более тонкое, кажется, что анимация ударилась о стену (медленно медленно), затем продолжаю отдых
так как я могу решить проблему? Я пробовал целый день, но я не мог это исправить
1 ответ
Документация для UISpringTimingParameters
говорит: https://developer.apple.com/documentation/uikit/uispringtimingparameters/1649832-init
Вектор с величиной 1,0 соответствует начальной скорости, которая покрывает общее расстояние анимации за одну секунду. Например, если общее расстояние анимации составляет 200 точек, а начальная скорость просмотра составляет 100 точек в секунду, укажите вектор с величиной 0,5.
Это означает, что вы должны нормализовать скорость с помощью вида.
И, глядя на официальную документацию для 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)
Дайте мне знать, если это сработало для вас.