如何为倒计时器创建循环进度指示器 [英] How to create a circular progress indicator for a count down timer

查看:185
本文介绍了如何为倒计时器创建循环进度指示器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的应用添加倒计时,但我遇到了动画问题。我想要的外观类似于下面显示的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆