Add a delay to a for loop in swift

后端 未结 6 1551
感动是毒
感动是毒 2021-01-05 08:02

I have a coding \'issue\'.

I have a label, which text I want to change dynamically every 2 seconds. I\'ve done the following:

// WELCOME STRING ARRA         


        
相关标签:
6条回答
  • 2021-01-05 08:30

    If you want to keep it all inline you can do this:

    var loop: ((Int) -> Void)!
    loop = { [weak self] count in
      guard count > 0 else { return }
      //Do your stuff
      DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        loop(count - 1)
      }
    }
    loop(10) //However many loops you want
    
    0 讨论(0)
  • 2021-01-05 08:35

    You can also use this function to delay something

    //MARK: Delay func 
    
    func delay(_ delay:Double, closure:@escaping ()->()) {
        DispatchQueue.main.asyncAfter(
            deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
    }
    

    and usage is :

            delay(2)  //Here you put time you want to delay
    {
                //your delayed code
            }
    

    Hope it will help you.

    0 讨论(0)
  • 2021-01-05 08:42

    You can add sleep function

    for i in 0..<welcomeContainer.count {
        welcomeLabel.text = welcomeContainer[i]
        sleep(2) // or sleep(UInt32(0.5)) if you need Double
    }
    
    0 讨论(0)
  • 2021-01-05 08:50

    With Timer, you should be careful to call invalidate of the Timer in viewDidDisappear or else you may not release the view controller.

    Alternatively, you can use a GCD dispatch timer, in which you completely eliminate the strong reference cycle by using [weak self] pattern:

    @IBOutlet weak var welcomeLabel: UILabel!
    
    var timer: DispatchSourceTimer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let welcomeStrings = ["Welcome", "Benvenuti", "Bienvenue", "Willkommen", "üdvözlet", "Dobrodošli", "добро пожаловать", "Witajcie", "Bienvenido", "Ласкаво просимо", "Vitajte", "欢迎你来"]
        var index = welcomeStrings.startIndex
        timer = DispatchSource.makeTimerSource(queue: .main)
        timer.scheduleRepeating(deadline: .now(), interval: .seconds(2))
        timer.setEventHandler { [weak self] in
            self?.welcomeLabel.text = welcomeStrings[index]
            index = index.advanced(by: 1)
            if index == welcomeStrings.endIndex {
                index = welcomeStrings.startIndex // if you really want to stop the timer and not have this repeat, call self?.timer.cancel()
            }
        }
        timer.resume()
    }
    
    0 讨论(0)
  • 2021-01-05 08:53

    Marked answer doesn't delay loop iterations and you still get just the last value in the label.text.

    You can solve it like this:

    func showWelcome(_ iteration: Int = 0) {
        let i = iteration>=self.welcomeContainer.count ? 0 : iteration
        let message = self.welcomeContainer[i]
        self.delay(2){
            self.welcomeLabel.text = message
            return self.showWelcome(i + 1)
        }
    }
    

    Usage:

        showWelcome()
    
    0 讨论(0)
  • 2021-01-05 08:54

    define those variables

    var i = 0
    let timer : Timer?
    

    Place this timer in your view did load or wherever you want to start the label change

       timer =  Timer.scheduledTimer(timeInterval: 2.0, target: self, selector:#selector(YourViewController.changeText), userInfo: nil, repeats: true)
    

    and implement this method:

    func changeText(){
        if i>=welcomeContainer.count {
            i = 0
        }
    
        welcomeLabel.text = welcomeContainer[i]
        i += 1
    }
    

    when you want to stop it or change the view controller dont forget to call

    timer.invalidate()
    
    0 讨论(0)
提交回复
热议问题