gpt4 book ai didi

iOS 相当于 Android ValueAnimator

转载 作者:行者123 更新时间:2023-12-03 08:45:42 28 4
gpt4 key购买 nike

我想要一些能够模仿 Android 中 ValueAnimator 在 iOS 中的行为的东西。在正常情况下,我会使用 UIView 动画,但不幸的是,我尝试随时间插值的对象值不适用于普通动画。

在我的特殊情况下,我使用 Lottie 动画,并尝试通过 UIView 动画更改动画的进度,但不是动画更改值随着时间的推移,它只是跳转到最终值。例如:

let lottieAnim = ...
lottieAnim.animationProgress = 0

UIView.animate(withDuration: 2) {
lottieAnim.animationProgress = 1
}

此示例不会随着时间的推移对 Lottie 动画进行动画处理,而只是跳到末尾。我知道lottie有播放动画的方法,但我尝试使用自定义动画曲线来设置进度(它是一个没有有限持续时间的进度动画),这就是为什么我需要使用UIView插入值的动画。

我需要一些间歇性更新来模仿动画的东西,首先想到的是 Android ValueAnimator 类。

最佳答案

我编写了一个类,它将在某种程度上模仿 Android 的 ValueAnimator,并且允许您在需要时指定自己的动画曲线(默认只是线性的)

简单使用

let valueAnimator = ValueAnimator(duration: 2) { value in
animationView.animationProgress = value
}

valueAnimator.start()

高级用法

let valueAnimator = ValueAnimator(from: 0, to: 100, duration: 60, animationCurveFunction: { time, duration in
return atan(time)*2/Double.pi
}, valueUpdater: { value in
animationView.animationProgress = value
})

valueAnimator.start()

您可以随时取消它,也可以使用:

valueAnimator.cancel()

Swift 5 中的 Value Animator 类

// swiftlint:disable:next private_over_fileprivate
fileprivate var defaultFunction: (TimeInterval, TimeInterval) -> (Double) = { time, duration in
return time / duration
}

class ValueAnimator {

let from: Double
let to: Double
var duration: TimeInterval = 0
var startTime: Date!
var displayLink: CADisplayLink?
var animationCurveFunction: (TimeInterval, TimeInterval) -> (Double)
var valueUpdater: (Double) -> Void

init (from: Double = 0, to: Double = 1, duration: TimeInterval, animationCurveFunction: @escaping (TimeInterval, TimeInterval) -> (Double) = defaultFunction, valueUpdater: @escaping (Double) -> Void) {
self.from = from
self.to = to
self.duration = duration
self.animationCurveFunction = animationCurveFunction
self.valueUpdater = valueUpdater
}

func start() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .current, forMode: .default)
}

@objc
private func update() {

if startTime == nil {
startTime = Date()
valueUpdater(from + (to - from) * animationCurveFunction(0, duration))
return
}

var timeElapsed = Date().timeIntervalSince(startTime)
var stop = false

if timeElapsed > duration {
timeElapsed = duration
stop = true
}

valueUpdater(from + (to - from) * animationCurveFunction(timeElapsed, duration))

if stop {
cancel()
}
}

func cancel() {
self.displayLink?.remove(from: .current, forMode: .default)
self.displayLink = nil
}
}

您可能可以将其改进为更通用,但这符合我的目的。

关于iOS 相当于 Android ValueAnimator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61594608/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com