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

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

问题描述

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

定义一个方法来创建 UIBezierPath

define a method to create de UIBezierPath

startAngle at -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 = timeLeft
    // 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天全站免登陆