Swift 在iOS应用程序中使用计时器和循环平滑动画
我有一个具有星星评级的ViewController,看起来像这样(除了有10颗星星) 当用户为一些没有评级的对象打开ViewController时,我想用非常简单的方法将用户的注意力指向这些星星:设置星星高亮显示的动画(当每个字母一个接一个高亮显示时,在现实世界中的一些广告上可以看到这种行为)Swift 在iOS应用程序中使用计时器和循环平滑动画,swift,animation,timer,grand-central-dispatch,Swift,Animation,Timer,Grand Central Dispatch,我有一个具有星星评级的ViewController,看起来像这样(除了有10颗星星) 当用户为一些没有评级的对象打开ViewController时,我想用非常简单的方法将用户的注意力指向这些星星:设置星星高亮显示的动画(当每个字母一个接一个高亮显示时,在现实世界中的一些广告上可以看到这种行为) 一颗星突出显示 两颗星突出显示 三颗星突出显示 把它们都关掉 所以我就是这样做的 func delayWithSeconds(_ seconds: Double, completion: @escap
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
}
}
}
func delayWithSeconds(u0; seconds:Double,completion:@escaping()->()){
DispatchQueue.main.asyncAfter(截止日期:.now()+秒){
完成()
}
}
功能分级开始模拟(){
因为我在1…11{
无功定时器:双精度=0.6+双精度(i)*0.12
延时秒(计时器){
评级星级=(i<10)?双(i):0
}
}
}
这是怎么回事?我有一个名为delayWithSeconds的函数来延迟操作,我使用这个函数来延迟每个星号的高亮显示。0.6是动画开始前的初始延迟。高亮显示所有星星后-最后一步是关闭所有星星的高亮显示。
这个代码可以工作,但我不能说它是平滑的
我的问题是:
看看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
}
var displayLink:CADisplayLink?
让我们开始:Double=0
让结束:双=10
let持续时间:CFTimeInterval=5//s
var startTime:CFTimeInterval=0
让ratingStars=RatingView()
func create(){
displayLink=CADisplayLink(目标:自身,选择器:#选择器(勾号))
displayLink?.add(添加到:.main,forMode:.defaultRunLoopMode)
}
func tick(){
guard let link=displayLink else{
清理()
返回
}
如果startTime==0{//第一个勾号
startTime=link.timestamp
返回
}
设maxTime=startTime+持续时间
让currentTime=link.timestamp
保护currentTime
首先,这将使动画更加平滑。如果你想添加缓和,你仍然需要添加一些三角函数,但这应该不会太难
- CADisplaylink:
- 缓和曲线:
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
}
var displayLink:CADisplayLink?
让我们开始:Double=0
让结束:双=10
let持续时间:CFTimeInterval=5//s
var startTime:CFTimeInterval=0
让ratingStars=RatingView()
func create(){
displayLink=CADisplayLink(目标:自身,选择器:#选择器(勾号))
displayLink?.add(添加到:.main,forMode:.defaultRunLoopMode)
}
func tick(){
guard let link=displayLink else{
清理()
返回
}
如果startTime==0{//第一个勾号
startTime=link.timestamp
返回
}
设maxTime=startTime+持续时间
让currentTime=link.timestamp
保护currentTime
首先,这将使动画更加平滑。如果你想添加缓和,你仍然需要添加一些三角函数,但这应该不会太难
- CADisplaylink:
- 缓和曲线: