如何创build倒数计时器的循环进度指示器

我正在尝试为我的应用程序添加一个倒计时,并且在animation中遇到了问题。 我要去看的外观类似于下面显示的iPad倒计时,随着时钟倒数,红色条会增加。 在这里输入图像说明

最初,我创build了一个图像地图集,每倒计时半秒钟一个单独的图像,但这似乎需要大量的内存运行,因此崩溃的应用程序,所以我现在必须find一个替代scheme。

我一直在着色着色https://developer.apple.com/library/prerelease/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9看不到一种将精灵的一部分着色的方式,似乎整个精灵都会被改变。

有没有人知道如果着色会是一个select,或者有没有一种方法来减less图像使用的地图集?

谢谢

您可以使用CAShapeLayer并按照以下步骤对animation结束进行animation处理:

更新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") 

定义一个创buildde UIBezierPath的方法

开始angular度在-90˚和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添加到您的视图中:

 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() } } 

您可以使用此扩展名将度数转换为弧度并显示时间

 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 } } 

示例项目

伟大的代码和答案! 只是想我会build议以下。 我得到的时间显示为1:00,然后是0:60,我认为这可能是由于代码的“ceil”部分。

我改变了以下(也希望less于60的时间显示不同),它似乎已经消除了时间的重叠。

物有所值 …

 extension NSTimeInterval { var time:String { if self < 60 { return String(format: "%02d", Int(floor(self%60))) } else { return String(format: "%01d:%02d", Int(self/60), Int(floor(self%60))) } } }