2014-11-23 3 views
24

Я хочу активировать запуск анимации активности, а затем остановить через одну секунду.Задержка действий в Swift

Так кто-нибудь знает, как я мог это сделать?

class stuff { 
@IBOutlet weak var indicator: UIActivityIndicatorView! 

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

Благодарим за ответ.

+0

См. 'NSTimer' или' dispatch_after'. – Rob

ответ

71

dispatch_after() - стандартный способ отсрочки действий.

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

См: dispatch_after - GCD in swift?


Обновление для Swift 3.0

indicator.startAnimating() 

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

Однако, в духе Свифта 3.0, я думаю, что расширение DispatchQueue будет лучшим решением.

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

Это оставляет нас с очень хорошим

indicator.startAnimating() 

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

Update 2

Копания в 8.0 бета Xcode, я нашел public func +(time: DispatchTime, seconds: Double) -> DispatchTime. Так что, я думаю, это справедливо ...

indicator.startAnimating() 

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

Я не думаю, что есть необходимость в расширении DispatchQueue для чего-то это чистой уже.

-

Обновление для Swift 3.1

Существует новый синтаксис для Swift 3.1. Им просто нравится что-то менять, не так ли.

indicator.startAnimating() 

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

Ваш быстрый пример 3, похоже, не работает с последним быстрым 3.1 –

+2

@ zingle-dingle Спасибо за примечание: я обновил свой ответ. –

+0

@JefferyThomas Я должен поблагодарить вас за этот подробный ответ. +1 очень заслуженно! :-) –

9

Вот чище и более выразительный код, чтобы сделать это с помощью Swift 3,1 и 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() 
} 

Также .seconds(Int), .microseconds(Int) и .nanoseconds(Int) может использоваться на время.

7

С обновленного синтаксисом Swift 3 это становится

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

Новой прошивки 10 Timer has a block initializer, который выполняется в главном потоке. Это также немного более гибко, потому что вы можете взять ссылку на таймер и отменить его или перенести его после факта.

let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in 
    } 
Смежные вопросы