我正在对一个时钟指针进行动画处理,该时钟指针的CGFloat值从0到1。虽然我有动画,但我希望它更加平滑。作为输入变量的一部分,整个动画需要5秒钟。我怎样才能使它更平滑?
理想情况下,我想在5秒内将所有值从0改为1 ...
钟针可以完成360度旋转,但是有点不稳
@IBAction func start(_ sender: Any) {
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(launchTimer), userInfo: nil, repeats: true)
launchTimer()
}
func launchTimer() {
guard seconds < 4.9 else {
timer.invalidate()
seconds = 0
return
}
seconds += 0.1
clockView.currentPressure = CGFloat(seconds / 5)
clockView.setNeedsDisplay()
}
编辑
import UIKit
class GaugeView: UIView {
var currentPressure : CGFloat = 0.0
override func draw(_ rect: CGRect) {
StyleKitName.drawGauge(pressure: currentPressure)
}
}
答案 0 :(得分:0)
减小时间间隔以使动画更平滑。这样一来,看起来好像在四处滑动,而不是在值之间跳跃。
您还可以使用spritekit:
import SpriteKit
let wait = SKAction.wait(forDuration: 0.01)
let runAnim = SKAction.run {
launchTimer()
}
let n = SKNode()
n.run(SKAction.repeat(SKAction.sequence([wait, runAnim]), count: 500))
答案 1 :(得分:0)
Timer
不适合这种规模的动画。在任何情况下,100ms都不是一个好步骤,因为它不是帧速率(16.67ms)的倍数。一般来说,除非您有专门的问题,否则不应尝试进行手动动画处理。请参见UIView.animate(withDuration:...)
,这通常是您应如何对UI元素进行动画处理,以使系统为您处理进度。
有关手动动画的更多信息,请参见CABasicAnimation
,它将随着时间的推移更新属性。如果您需要非常手动的控制,请参见CADisplayLink
,但几乎不需要。
在任何情况下,您都绝不能假设任何计时器在您要求时被准确地调用。您不能仅仅因为要求在0.1s内调用而将0.1s加到值上。您必须查看实际时间。即使是硬实时系统也无法保证会在准确的时刻调用某些内容。您可能会得到的最好的保证是,它将在一定的容忍度内(iOS甚至没有给您)。
要使用UIView
(我推荐)对此进行动画处理,它可能类似于:
@IBAction func start(_ sender: Any) {
self.clockView.currentPressure = 0
UIView.animate(withDuration: 5, animations: {
self.clockView.currentPressure = 1
})
}
使用CABasicAnimation
(更为复杂),结果类似于:
currentPressure = 1 // You have to set it to where it's going or it'll snap back.
let anim = CABasicAnimation(keyPath: "currentPressure")
anim.fromValue = 0
anim.toValue = 1
anim.duration = 5
clockView.addAnimation(anim)