iOS 简单实现倒计时功能

倒计时功能在App中应用非常常见,例如启动微博启动页面的按钮,或者获取验证码计时,这里主要实现倒计时的基本功能

设计思路
  • 计时器:Timer
  • 触发计时器
  • 显示载体:UILabel

通过点击Label触发计时器开始计时,每一秒改变Label的问题,实现倒计时的效果


核心代码
override func viewDidLoad() {
        super.viewDidLoad()
        countDownLabel.text = "获取验证码"
        countDownLabel.backgroundColor = .gray
        // 激活Label点击功能,并添加手势,否则无法点击
        countDownLabel.isUserInteractionEnabled = true
        // 点击Label调用 startTimer 函数
        let tap = UITapGestureRecognizer(target: self, action: #selector(startTimer))
        countDownLabel.addGestureRecognizer(tap)
    }
    func startTimer() {
        // 每个一秒调用 updateTime 函数
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
        //激活计时器
        // Causes the timer's message to be sent to its target.
        timer.fire()
    }
func scheduledTimer(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool) -> Timer

官方对于各个参数的解释
ti: The number of seconds between firings of the timer. If ti is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.
target: The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.
aSelector: The message to send to target when the timer fires.
userInfo: The user info for the timer. The timer maintains a strong reference to this object until it (the timer) is invalidated. This parameter may be nil.
repeats: If true, the timer will repeatedly reschedule itself until invalidated. If false, the timer will be invalidated after it fires.

    func updateTime() {
        count = count - 1
        countDownLabel.text = "\(count)s"
        countDownLabel.isUserInteractionEnabled = false
        countDownLabel.backgroundColor = .lightGray

        if count == 0 {
            timer.invalidate()
            countDownLabel.text = "获取验证码"
            countDownLabel.isUserInteractionEnabled = true
            countDownLabel.backgroundColor = .gray
            count = 10
        }
    }
  • 经过以上几行简单的代码既可以实现一个粗糙的倒计时器,效果如下

现有问题

但是请仔细看,倒计时的过程中,Label会出现闪烁的情况
为了便于观察我为Lable添加了一个背景色


这是一个由字体引起的问题,在iOS 9以后,系统默认的英文字体变为了San Fransico,这个字体的每个数字宽度都不相等


解决方法
  • 替换字体
    用每个数字宽度相同的字体代替默认字体,如Helvetica
countDownLabel.font = UIFont(name: "Helvetica", size: 26)
  • 调用UIFont新的API使数字宽度一致
countDownLabel.font = UIFont.monospacedDigitSystemFont(ofSize: 26, weight: .regular)

以上两种方法皆可以解决Label闪烁的问题
这是对字体处理之后的效果,可以看到并不会想之前那样出现闪烁的情况



尊重原创,转载请注明出处,谢谢!
项目源码

你可能感兴趣的:(iOS 简单实现倒计时功能)