В более ранних версиях 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?
После долгих исследований я наконец понял это.
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.
Вдохновлен частью этого ответа.
Мне нравится однострочное обозначение для 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)
В этом сообщении в блоге вы можете найти более подробную информацию.
Попробуйте следующую функцию, реализованную в Swift 3.0 и выше
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
использование
delayWithSeconds(1) {
//Do something
}
Попробуйте приведенный ниже код для задержки
//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
}
//Запускает функцию через х секунд
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
}
Вы можете использовать это:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// do something with code
}
Я делаю это в Swift 4:
Thread.sleep(until: Date(timeIntervalSinceNow: 2.5))
Эта строка кода блокирует текущий поток до истечения указанного времени. Время задержки определяется в формате даты. Выше используемая версия инициализатора Date просто принимает значение секунды в формате Double. Это значение может иметь разрешение в миллисекундах.
Обратите внимание, что если вы вызовете этот код в главном потоке, пользовательский интерфейс остановится на указанное время.
DispatchQueue.main.asyncAfter(deadline: when)