Delay Actions in Swift

主宰稳场 提交于 2020-01-20 16:09:28

问题


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 weak var indicator: UIActivityIndicatorView!

   func iGotTriggeredBySomething {
      indicator.startAimating()
      //delay?
      indicator.stopAnimating()
   }
}

Thanks for answering.


回答1:


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()
}



回答2:


With the updated Swift 3 syntax this becomes

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    indicator.stopAnimating()
}



回答3:


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.




回答4:


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 
    }


来源:https://stackoverflow.com/questions/27085009/delay-actions-in-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!