如何为倒计时器创建循环进度指示器 [英] How to create a circular progress indicator for a count down timer
问题描述
我正在尝试为我的应用添加倒计时,但我遇到了动画问题。我想要的外观类似于下面显示的iPad倒计时,红色条随着时钟倒计时而增加。
I am trying to add a countdown to my app and I'm having problems animating this. The look I'm going for is something similar to the iPad countdown shown below, with the red bar increasing as the clock counts down.
最初我创建了一个图像地图集,每个倒计时的半秒都有一个单独的图像,但这似乎需要大量的内存才能运行,因此崩溃应用程序,所以我现在必须找到一个替代方案。
Initially I created an image atlas with an individual image for each half second of the countdown but this seems to take a lot of memory to run and therefore crashes the app so I now have to find an alternative.
我一直在寻找着色的颜色 https://developer.apple.com/library/prerelease/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG /Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9 但看不到一种为精灵部分着色的方法,似乎整个精灵都会被改变。
I've been looking at colorizing here https://developer.apple.com/library/prerelease/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9 but can't see a way of colorizing a section of the sprite, it seems that the whole sprite would be changed.
有没有人知道在这里是否可以选择着色,还是有办法减少图像地图集使用的内存?
Does anyone know if colorizing would be an option here, or is there a way of reduce the memory used by an image atlas?
谢谢
推荐答案
你可以使用CAShapeLayer和动画结束动画如下:
You can do it using CAShapeLayer and animating the stroke end as follow:
更新 Xcode 9•Swift 4
定义剩余时间
let timeLeftShapeLayer = CAShapeLayer()
let bgShapeLayer = CAShapeLayer()
var timeLeft: TimeInterval = 60
var endTime: Date?
var timeLabel = UILabel()
var timer = Timer()
// here you create your basic animation object to animate the strokeEnd
let strokeIt = CABasicAnimation(keyPath: "strokeEnd")
定义创建de UIBezierPath的方法
define a method to create de UIBezierPath
startAngle在-90˚和endAngle 270
startAngle at -90˚ and endAngle 270
func drawBgShape() {
bgShapeLayer.path = UIBezierPath(arcCenter: CGPoint(x: view.frame.midX , y: view.frame.midY), radius:
100, startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true).cgPath
bgShapeLayer.strokeColor = UIColor.white.cgColor
bgShapeLayer.fillColor = UIColor.clear.cgColor
bgShapeLayer.lineWidth = 15
view.layer.addSublayer(bgShapeLayer)
}
func drawTimeLeftShape() {
timeLeftShapeLayer.path = UIBezierPath(arcCenter: CGPoint(x: view.frame.midX , y: view.frame.midY), radius:
100, startAngle: -90.degreesToRadians, endAngle: 270.degreesToRadians, clockwise: true).cgPath
timeLeftShapeLayer.strokeColor = UIColor.red.cgColor
timeLeftShapeLayer.fillColor = UIColor.clear.cgColor
timeLeftShapeLayer.lineWidth = 15
view.layer.addSublayer(timeLeftShapeLayer)
}
添加你的标签
func addTimeLabel() {
timeLabel = UILabel(frame: CGRect(x: view.frame.midX-50 ,y: view.frame.midY-25, width: 100, height: 50))
timeLabel.textAlignment = .center
timeLabel.text = timeLeft.time
view.addSubview(timeLabel)
}
在viewDidload中设置endTime并将CAShapeLayer添加到视图中:
at viewDidload set the endTime and add your CAShapeLayer to your view:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(white: 0.94, alpha: 1.0)
drawBgShape()
drawTimeLeftShape()
addTimeLabel()
// here you define the fromValue, toValue and duration of your animation
strokeIt.fromValue = 0
strokeIt.toValue = 1
strokeIt.duration = 60
// add the animation to your timeLeftShapeLayer
timeLeftShapeLayer.add(strokeIt, forKey: nil)
// define the future end time by adding the timeLeft to now Date()
endTime = Date().addingTimeInterval(timeLeft)
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}
更新时间
@objc func updateTime() {
if timeLeft > 0 {
timeLeft = endTime?.timeIntervalSinceNow ?? 0
timeLabel.text = timeLeft.time
} else {
timeLabel.text = "00:00"
timer.invalidate()
}
}
您可以使用此扩展程序将度数转换为弧度并显示时间
you can use this extension to convert the degrees to radians and display time
extension TimeInterval {
var time: String {
return String(format:"%02d:%02d", Int(self/60), Int(ceil(truncatingRemainder(dividingBy: 60))) )
}
}
extension Int {
var degreesToRadians : CGFloat {
return CGFloat(self) * .pi / 180
}
}
这篇关于如何为倒计时器创建循环进度指示器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!