ios - 如何为倒数计时器创建循环进度指示器

标签 ios swift animation timer sprite-kit

我正在尝试向我的应用程序添加倒计时,但我在设置动画时遇到了问题。我想要的外观类似于下面显示的 iPad 倒计时,红色条随着时钟倒计时而增加。 enter image description here

最初,我为倒计时的每半秒创建了一个包含单独图像的图像集,但这似乎需要大量内存才能运行,因此导致应用程序崩溃,所以我现在必须找到替代方案。

我一直在看这里的着色https://developer.apple.com/library/prerelease/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9但看不到为 Sprite 的一部分着色的方法,似乎整个 Sprite 都会改变。

有谁知道着色是否是这里的一个选项,或者是否有减少图像图集使用的内存的方法?

谢谢

最佳答案

您可以使用 CAShapeLayer 并为笔画末端设置动画,如下所示:

更新 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 的方法

startAngle 在 -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 设置结束时间并将您的 CAShapeLayer 添加到您的 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()
    }
}

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

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

Sample project

关于ios - 如何为倒数计时器创建循环进度指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30289173/

相关文章:

swift - Swift 中 AnyClass 的 Dart 表示是什么

jQuery animate() 和 CSS 过渡在同一事件上分别发生

ios - 单击我的按钮时,无法识别的选择器发送到实例错误

objective-c - 将曲线拟合到一组点

swift - 某些文档功能在 Xcode 8 中不起作用

ios - CGPath 的错误比例 - Swift

python - 使用matplotlib.pyplot制作一维波动方程的动画

java - 如何使用弧度移动物体?

ios - 如何使 UIScrollview 一次只显示一个 subview

ios - 如何在 Swift 中访问不同 View Controller 中的数组中的值?