iOS 进度条动画、秒表计时器

作者: Guomingjian | 来源:发表于2018-03-26 15:42 被阅读77次

    前段时间公司项目要新增一个副卡录音功能,效果图包含秒表计时器,底部一个计时进度条的动画。现在跟大家分享,欢迎大家交流o( ̄︶ ̄)o

    ·效果展示:
    新增录音.gif
    ·大家有一卡多号需求的可以下载:和多号
    ·实现过程
    1、HDHTimerView.xib
    TimeViewXib.png
    2、HDHTimerView.swift

    定义计时完成block(假设自定义秒数seconds=10s,则当计数到10,进度条为100%)

    typealias completeCallback = (_ seconds : Int) -> Void
    
    class HDHTimerView: UIView {
    
        //MARK:-
        @IBOutlet weak private var minutesLabel: UILabel!
        @IBOutlet weak private var secondsLabel: UILabel!
        @IBOutlet weak private var msLabel: UILabel!
        
        //MARK:-
        fileprivate var countTimer : Timer?
        fileprivate var minutes : Int = 0   //分
        fileprivate var seconds : Int = 0   //秒
        fileprivate var ms : Int = 0        //毫秒
        
        //MARK:- 外部属性
        var maxSeconds : Int = 10 { //计时器停止时间.(单位秒,默认10)
            didSet {
                if maxSeconds < 0 || maxSeconds > 3600 {
                    maxSeconds = 10
                }
            }
        }
        var timeCompleteBlock : completeCallback?
    
    }
    

    外部调用API(方法前加@objc 为了供OC文件调用,fileprivate关键字是本文件内才有权限访问)

    //MARK:-
    extension HDHTimerView
    {
        //MARK:- 外部方法
        /// 计数器开始
        func start ()
        {
            stop()
            countTimer = Timer.init(timeInterval: 0.01, target: self, selector: #selector(self.timeRunning), userInfo: nil, repeats: true)
            RunLoop.main.add(countTimer!, forMode: .commonModes)
        }
        
        /// 计数器暂停
        func stop()
        {
            countTimer?.invalidate()
            countTimer = nil
        }
        
        /// 计数器复位
        func reset()
        {
            stop()
            minutes = 0
            seconds = 0
            ms = 0
            updateUI()
        }
        
        //MARK:-
        //开始计数
        @objc fileprivate func timeRunning()
        {
            ms += 1
            
            if ms == 100 {
                seconds += 1
                ms = 0;
            }
            
            if seconds == 60 {
                minutes += 1;
                seconds = 0;
            }
            
            let totalTime = self.getTotalTime()
            if (totalTime == maxSeconds * 100) {
                if timeCompleteBlock != nil {
                    timeCompleteBlock!(maxSeconds)
                    self.stop()
                }
            }
            
            if minutes == 60 {
                self.reset()
            }
            
            self.updateUI()
        }
    
        //获取当前计时总时间(毫秒)
        func getTotalTime() -> (Int) {
    
            var totalTime = ms
            totalTime += seconds * 100
            totalTime += minutes * 60 * 100
    
            return totalTime
        }
        
        //刷新UI
        fileprivate func updateUI()
        {
            minutesLabel.text = String.init(format: "%02d", minutes)
            secondsLabel.text = String.init(format: "%02d", seconds)
            msLabel.text = String.init(format: "%02d", ms)
        }
    }
    
    //MARK:- 从xib中快速创建的类方法
    extension HDHTimerView
    {
        class func getTimerView() -> HDHTimerView
        {
            return Bundle.main.loadNibNamed("HDHTimerView", owner: nil, options: nil)?.first as! HDHTimerView
        }
    }
    

    调用示例:

    //定义懒加载
    fileprivate lazy var hdhTimeView : HDHTimerView = {
            let timeView = HDHTimerView.getTimerView()
            timeView.maxSeconds = kMaxSeconds
            //        timeView.backgroundColor = UIColor.groupTableViewBackground
            let x = (kScreenW - timeView.frame.size.width) / 2.0
            let rect = CGRect.init(x: x, y: 100, width: timeView.frame.size.width, height: timeView.frame.size.height)
            timeView.frame = rect
            
            return timeView
        }()
    
      //调用
    view.addSubview(hdhTimeView)
    hdhTimeView.timeCompleteBlock = { (maxSeconds) in
                //print("计时到了:\(maxSeconds)秒")
                self.stateLabel.text = "录音完成"
            }
    

    3、HDHProgressBarView.xib

    进度条View初始长度为0,通过计时所占目标时间的百分比从而改变长度。

    HDHProgressBarView.xib
    4、HDHProgressBarView.swift
    class HDHProgressBarView: UIView {
        
        //MARK:-
        @IBOutlet weak private var contentView: UIView!
    
        //MARK:- 外部属性
        var progressBarBackgroundColor : UIColor = UIColor.green {
            didSet {
                contentView.backgroundColor = progressBarBackgroundColor
            }
        }
        var finishedTime : Int = 10 { //进度条完成所需时间,默认10秒
            didSet {
                if  finishedTime < 0 {
                    finishedTime = 10
                }
            }
        }
        var refreshFrequency : TimeInterval = 0.1 { //进度条刷新频率(秒)
            didSet {
                if refreshFrequency > 2 || refreshFrequency < 0.01 {
                    refreshFrequency = 0.1
                }
            }
        }
        
        //MARK:-
        fileprivate var progressTimer : Timer?
        fileprivate var currentRunTime : CGFloat = 0 //当前进度时间(秒)
        fileprivate var percentage : CGFloat = 0 //进度百分比
        
    }
    

    外部API

    //MARK:-
    extension HDHProgressBarView
    {
        //MARK:- 外部方法
        /// 进度条开始
        func start ()
        {
            stop()
            progressTimer = Timer.init(timeInterval: refreshFrequency, target: self, selector: #selector(self.timeRunning), userInfo: nil, repeats: true)
            RunLoop.main.add(progressTimer!, forMode: .commonModes)
        }
        
        /// 进度条暂停
        func stop()
        {
            progressTimer?.invalidate()
            progressTimer = nil
        }
        
        /// 进度条复位
        func reset()
        {
            stop()
            currentRunTime = 0
            percentage = 0
            updateUI()
        }
        
        //MARK:-
        //进度开始加载
        @objc fileprivate func timeRunning()
        {
            currentRunTime += CGFloat(refreshFrequency)
            if currentRunTime > CGFloat(finishedTime)
            {
                self.stop()
                return
            }
            percentage = currentRunTime / CGFloat(finishedTime)
            self.updateUI()
        }
        
        //刷新UI
        fileprivate func updateUI()
        {
            UIView.animate(withDuration: refreshFrequency) {
                var frame = self.contentView.frame
                let width = self.percentage * CGFloat(self.frame.size.width)
                frame.size.width = width
                self.contentView.frame = frame
            }
        }
    }
    
    //MARK:- 从xib中快速创建的类方法
    extension HDHProgressBarView
    {
        class func getProgressBarView() -> HDHProgressBarView
        {
            return Bundle.main.loadNibNamed("HDHProgressBarView", owner: nil, options: nil)?.first as! HDHProgressBarView
        }
    }
    

    调用示例:

    //懒加载
    fileprivate lazy var hdhProgressBarView : HDHProgressBarView = {
            let progressBarView = HDHProgressBarView.getProgressBarView()
            progressBarView.frame = CGRect(x: 0, y: 250, width: kScreenW, height: progressBarView.frame.size.height)
            progressBarView.finishedTime = kMaxSeconds
            
            return progressBarView
        }()
    
    //调用
    view.addSubview(hdhProgressBarView)
    

    Demo下载

    相关文章

      网友评论

        本文标题:iOS 进度条动画、秒表计时器

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