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

前段时间公司项目要新增一个副卡录音功能,效果图包含秒表计时器,底部一个计时进度条的动画。现在跟大家分享,欢迎大家交流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 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,222评论 4 61
  • 从太原(二线落后城市)大学毕业(普通一本)后来到西安(相对太原发展快一些)工作,准备以后在这里定居。近期深切地感受...
    小小Mark阅读 1,027评论 0 1
  • "为了人类的和平和进步,中国人来到太空了!"[鼓掌][鼓掌][鼓掌] 民族精神并不遥远,她一直流淌在我们的血液里,...
    淡淡湾阅读 3,996评论 0 0
  • 姬老师开篇说幸福是什么。 说来说去幸福就是具有平衡关系的能力。 幸福就是具有解决问题的能力 幸福就是具有克服困难的...
    和艳红阅读 2,578评论 1 1
  • 百花传香,岁月含情。 好久也不算太久,时光如同白驹过隙。好难也不算太难,一路走来我们相互扶持。我穿过一条长长的小道...
    芷墨l阅读 5,048评论 18 20