我的ViewController的星级评分如此(除了有10颗星)
当用户为某些没有评级的对象打开ViewController时,我想用非常简单的方式指出用户对这些星星的关注:动画明星突出显示(你可以在每个字母的现实世界中看到这样的行为)一个接一个地突出显示)。
所以这就是我这样做的方式
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
func ratingStarsAnimation() {
for i in 1...11 {
var timer : Double = 0.6 + Double(i)*0.12
delayWithSeconds(timer) {
ratingStars.rating = (i < 10) ? Double(i) : 0
}
}
}
这里发生了什么?我有一个名为delayWithSeconds的函数来延迟动作,我使用这个函数来延迟每个星形突出显示。 0.6是动画开始前的初始延迟。在所有星星突出显示后 - 最后一步是关闭所有星星的突出显示。 这段代码有效,但我不能说它很顺利。
我的问题是:
答案 0 :(得分:2)
查看CADisplaylink类。它是一个专门的计时器,链接到屏幕的刷新率,在iOS上这是60fps。 它是许多第三方动画库的支柱。
用法示例:
var displayLink: CADisplayLink?
let start: Double = 0
let end: Double = 10
let duration: CFTimeInterval = 5 // seconds
var startTime: CFTimeInterval = 0
let ratingStars = RatingView()
func create() {
displayLink = CADisplayLink(target: self, selector: #selector(tick))
displayLink?.add(to: .main, forMode: .defaultRunLoopMode)
}
func tick() {
guard let link = displayLink else {
cleanup()
return
}
if startTime == 0 { // first tick
startTime = link.timestamp
return
}
let maxTime = startTime + duration
let currentTime = link.timestamp
guard currentTime < maxTime else {
finish()
return
}
// Add math here to ease the animation
let progress = (currentTime - startTime) / duration
let progressInterval = (end - start) * Double(progress)
// get value =~ 0...10
let normalizedProgress = start + progressInterval
ratingStars.rating = normalizedProgress
}
func finish() {
ratingStars.rating = 0
cleanup()
}
func cleanup() {
displayLink?.remove(from: .main, forMode: .defaultRunLoopMode)
displayLink = nil
startTime = 0
}
首先,这将使您的动画更加流畅。如果你想添加缓动,你仍然需要添加一些三角函数,但这不应该太困难。