Как запрограммировать задержку в Swift 3

В более ранних версиях Swift можно создать задержку со следующим кодом:

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
    //put your code which should be executed with a delay here
}

Но теперь, в Swift 3, Xcode автоматически изменяет 6 разных вещей, но затем появляется следующая ошибка: "Невозможно преобразовать DispatchTime.now в ожидаемое значение dispatch_time_t aka UInt64."

Как создать задержку перед запуском последовательности кода в Swift 3?

Ответ 1

После долгих исследований я наконец понял это.

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change '2.0' to the desired number of seconds.
   // Code you want to be delayed
}

Это создает желаемый эффект ожидания в Swift 3 и Swift 4.

Вдохновлен частью этого ответа.

Ответ 2

Мне нравится однострочное обозначение для GCD, оно более элегантное:

    DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
        // do stuff 42 seconds later
    }

Кроме того, в iOS 10 у нас есть новые методы Таймера, например. Инициализатор блока:

(поэтому отложенное действие может быть отменено)

    let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
        // do stuff 42 seconds later
    }

Btw, имейте в виду: по умолчанию таймер добавляется в режим цикла запуска по умолчанию. Это означает, что таймер может быть заморожен, когда этот режим цикла приостановлен (например, при прокрутке UIScrollView) Вы можете решить эту проблему, добавив таймер в конкретный режим цикла запуска:

RunLoop.current.add(timer, forMode: .commonModes)

В этом сообщении в блоге вы можете найти более подробную информацию.

Ответ 3

Попробуйте следующую функцию, реализованную в Swift 3.0 и выше

func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
        completion()
    }
}

использование

delayWithSeconds(1) {
   //Do something
}

Ответ 4

Попробуйте приведенный ниже код для задержки

//MARK: First Way

func delayForWork() {
    delay(3.0) {
        print("delay for 3.0 second")
    }
}

delayForWork()

// MARK: Second Way

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your code here delayed by 0.5 seconds
}

Ответ 5

//Запускает функцию через х секунд

public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) {
    runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after)
}

public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) {
    let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    queue.asyncAfter(deadline: time, execute: after)
}

//Использование: -

runThisAfterDelay(seconds: x){
  //write your code here
}

Ответ 6

Вы можете использовать это:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    // do something with code 
}

Ответ 7

Одним из способов является использование DispatchQueue.main.asyncAfter как многие люди ответили.

Другой способ - использовать perform(_:with:afterDelay:). Подробнее здесь

perform(#selector(delayedFunc), with: nil, afterDelay: 3)

@IBAction func delayedFunc() {
    // implement code
}

Ответ 8

Я делаю это в Swift 4:

Thread.sleep(until: Date(timeIntervalSinceNow: 2.5))

Эта строка кода блокирует текущий поток до истечения указанного времени. Время задержки определяется в формате даты. Выше используемая версия инициализатора Date просто принимает значение секунды в формате Double. Это значение может иметь разрешение в миллисекундах.

Обратите внимание, что если вы вызовете этот код в главном потоке, пользовательский интерфейс остановится на указанное время.