美文网首页
环形倒计时

环形倒计时

作者: Michale_Zuo | 来源:发表于2018-08-08 15:47 被阅读0次

    以前项目中有一个小小的需求,是圆形倒计时view,话不多说请看图


    circle.gif

     怎么实现这样的需求了?
     圆形可以通过贝塞尔曲线画出来,倒计时可以通过NSTimer或者CADisplayLink来实现,我选择的是后者,后者的刷新频率是1/60s,和UI的刷新屏幕是一毛一样的,可以避免卡顿的问题。

    // 默认init方法起始点在CGFloat.pi * (-0.5)圆的最上方
    //drawView = MZDrawView(frame: CGRect(x: 100, y: 100, width: 100, height: 200))
    // 当然也可以设置圆的起始点
    drawView = MZDrawView(frame: CGRect(x: 100, y: 100, width: 100, height: 100), angle: CGFloat.pi * (0.5))
    drawView?.backPathColor = UIColor.red
    drawView?.cycleColor = UIColor.cyan
    // 倒计时时间
    drawView?.duration = 10
    // 半径 (不设置的话就默认为MZDrawView的最大内切圆的半径)
    drawView?.radius = 20
    self.view.addSubview(drawView!)
    
    
    • 初始化DrawView,可以指定起始点
    // MARK: init func
        
        convenience init(frame: CGRect ,angle:CGFloat) {
            self.init(frame: frame)
            self.angle = angle
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.addSubview(self.timerLabel)
            let width = self.frame.size.width - lineWidth * 2 - Margin * 2
            let height = self.frame.size.height - lineWidth * 2 - Margin * 2
            self.timerLabel.frame = CGRect(x: (self.frame.size.height - height)  * 0.5, y: (self.frame.size.width - width)  * 0.5, width: width, height: height)
            self.timerLabel.textColor = textColor ?? UIColor.white
            
        }
    
    • drawView的基本属性可以设置倒计时view的样式
     /// 圆圈的宽度
        var lineWidth: CGFloat = 5.0
        private var displayLink: CADisplayLink?
        var backPathColor: UIColor = UIColor.clear
        /// 圆圈颜色
        var cycleColor: UIColor?
        /// 倒计时时间label的文字颜色
        var textColor: UIColor? {
            didSet {
                self.timerLabel.textColor = textColor ?? UIColor.white
            }
        }
        // 默认起始和结束都在圆的顶点
        var angle: CGFloat = CGFloat.pi * (-0.5)
        /// 自定义半径
        var radius: CGFloat = 0.0
        /// 自定义圆的中心点
        var cycleCenter: CGPoint = CGPoint.zero
        // 倒计时时间
        var duration: Double = 0.0 {
            didSet {
                if duration < 0.0 { return }
                // 先停掉link
                invalidateLink()
                // 在开启link
                self.displayLink = CADisplayLink(target: self, selector: #selector(countDown))
                self.displayLink?.add(to: RunLoop.current, forMode: .commonModes)
                
            }
        }
        // 当前进度
        var progress: Double = 1.0 {
            didSet {
                if progress < 0 || progress > 1 {
                    return
                }
                // ceil(返回不小于x的最小整数值)
                self.timerLabel.text = "\(ceil(self.progress * duration))"
                self.setNeedsDisplay()
            }
        }
    
    • invalid计时器方法

      当计时器还在work的时候,如果不需要使用了一定要停掉计时器
      当计时器还在work的时候,如果不需要使用了一定要停掉计时器
      当计时器还在work的时候,如果不需要使用了一定要停掉计时器

    /// 在不用的时候要call一下 停掉link
        // 比如 vc的deinit方法里
        open func invalidateLink() {
            guard let displayLink = self.displayLink else {
                return
            }
            displayLink.isPaused = true
            displayLink.invalidate()
        }
    
    • 根据时间计算比例然后画圆
    /// 倒计时 1/60s调用一次
        @objc private func countDown() {
            if progress < 0.0 || progress > 1.0 {
                invalidateLink()
                self.progress = 0.0
                return
            }
            self.progress -= Double((1/60) / self.duration)
        }
    

    详情请见demo

    相关文章

      网友评论

          本文标题:环形倒计时

          本文链接:https://www.haomeiwen.com/subject/uckxbftx.html