iOS开发攻城狮的集散地视图控件iOS开发-学习记录

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

2018-03-26  本文已影响77人  Guomingjian

前段时间公司项目要新增一个副卡录音功能,效果图包含秒表计时器,底部一个计时进度条的动画。现在跟大家分享,欢迎大家交流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下载

上一篇下一篇

猜你喜欢

热点阅读