使用Timer.scheduledTimer的Swift4动画

时间:2018-07-23 14:53:16

标签: swift animation timer

我正在对一个时钟指针进行动画处理,该时钟指针的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)
    }
}

2 个答案:

答案 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)