Delay Actions in Swift

后端 未结 4 583
长情又很酷
长情又很酷 2020-12-24 11:58

I want to make an Activity Indicator start animating and then stop after one second.

So does anyone know how I could do that?

class stuff {
@IBOutlet         


        
相关标签:
4条回答
  • 2020-12-24 12:39

    dispatch_after() is the standard way of delaying actions.

    indicator.startAnimating()
    
    let delay = 4.5 * Double(NSEC_PER_SEC)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
    dispatch_after(time, dispatch_get_main_queue()) {
        indicator.stopAnimating()
    }
    

    See: dispatch_after - GCD in swift?


    Update for Swift 3.0

    indicator.startAnimating()
    
    let delay = Int(4.5 * Double(1000))
    DispatchQueue.main.after(when: .now() + .milliseconds(delay)) {
        indicator.stopAnimating()
    }
    

    However, in the spirit of Swift 3.0, I think extending DispatchQueue would be a better solution.

    extension DispatchQueue {
        func delay(_ timeInterval: TimeInterval, execute work: () -> Void) {
            let milliseconds = Int(timeInterval * Double(1000))
            after(when: .now() + .milliseconds(milliseconds), execute: work)
        }
    }
    

    This leaves us with a very nice

    indicator.startAnimating()
    
    DispatchQueue.main.delay(4.5) {
        indicator.stopAnimating()
    }
    

    Update 2

    Digging into the Xcode 8.0 beta, I found public func +(time: DispatchTime, seconds: Double) -> DispatchTime. So, I guess this is valid…

    indicator.startAnimating()
    
    DispatchQueue.main.after(when: .now() + 4.5) {
        indicator.stopAnimating()
    }
    

    I don't think there is a need to extend DispatchQueue for something this clean already.

    --

    Update for Swift 3.1

    There is new syntax for Swift 3.1. They just likes to change things don't they.

    indicator.startAnimating()
    
    DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
        indicator.stopAnimating()
    }
    
    0 讨论(0)
  • 2020-12-24 12:41

    With the updated Swift 3 syntax this becomes

    DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
        indicator.stopAnimating()
    }
    
    0 讨论(0)
  • 2020-12-24 12:46

    New in iOS 10, Timer has a block initializer that executes on the main thread. Its also slightly more flexible because you can take a reference to the Timer and cancel it or reschedule it after the fact.

        let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in 
        }
    
    0 讨论(0)
  • 2020-12-24 12:48

    Here is a cleaner and more expressive code to do this using Swift 3.1 and Grand Central Dispatch:

    Swift 3.1:

    indicator.startAnimating()
    
    // Runs after 1 second on the main queue.
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) { 
        indicator.stopAnimating()
    }
    

    Also .seconds(Int), .microseconds(Int) and .nanoseconds(Int) may be used for the time.

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