Timers can be set to perform an operation at a fixed period. There are three main types of Timer in iOS, the first of which is explained in this article.

use

  • After iOS 10, the following method does not have the problem of circular reference and is recommended.
// Automatic Timer
// Parameter 1: time interval. Parameter 2: whether to repeat the execution
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in  
    // Code that executes periodically
    print("Hello World")}// The Timer needs to be manually enabled
let timer = Timer(timeInterval: 2.0, repeats: true) { (timer) in  
    // Code that executes periodically
    print("Hello World")}Copy the code

RunLoop

  • A loop that handles events and keeps the program running. When the App starts, a main thread will be opened, and a RunLoop will run when the main thread is started. The RunLoop ensures that the main thread will not be destroyed, thus keeping the program running.
  • RunLoop can work in five common modes:
    • default: Default mode.
    • tracking: Interface tracing mode.
    • common: General mode, a combination of the previous two.
  • Adding a Timer to a RunLoop automatically starts working.
// The interface will stop when it is dragged
RunLoop.current.add(timer, forMode: .default)
// Interface drag is executed
RunLoop.current.add(timer, forMode: .tracking)
// A combination of the above two modes is commonly used
RunLoop.current.add(timer, forMode: .common)
Copy the code

Pause and Restart

/ / pause
timer.fireDate = Date.distantFuture
/ / restart
timer.fireDate = Date.distantPast
Copy the code

The destruction

Invalidate: Prevents the Timer from firing again and requesting its removal from the RunLoop, so it cannot be restarted after this mode is stopped.

timer.invalidate()
Copy the code

Case study: Countdown

import UIKit

class ViewController: UIViewController {
    // Total countdown time (seconds)
    var count = 5
    / / timer
    var timer: Timer!
    // UILabel+UITapGestureRecognizer is better than UIButton
    lazy var label: UILabel = {
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
        label.center = view.center
        label.text = "Get countdown"
        label.textAlignment = .center
        label.isUserInteractionEnabled = true
        label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleCount)))
        return label
    }()

    override func viewDidLoad(a) {
        super.viewDidLoad()

        view.addSubview(label)
    }

    @objc func handleCount(a) {
        // No clicking is allowed during the countdown
        label.isUserInteractionEnabled = false

        // Create a Timer every 1s
        timer = Timer(timeInterval: 1.0, repeats: true) { _ in
            // Display the countdown
            self.label.text = "\ [self.count)"
            // Time minus 1
            self.count - = 1
            // When the timer is 0
            if self.count = = 0 {
                // Stop the timer
                self.timer.invalidate()
                // Change the text
                self.label.text = "Recapture"
                // Allow interaction
                self.label.isUserInteractionEnabled = true
                // Total restoration countdown time
                self.count = 5}}// Add RunLoop and the timer starts working
        RunLoop.current.add(timer, forMode: .common)
    }
}
Copy the code