Swift 3で遅延をプログラムする方法


330

以前のバージョンの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_takaに変換できませんUInt64。」

Swift 3で一連のコードを実行する前に遅延を作成するにはどうすればよいですか?

回答:


966

多くの調査の結果、私はようやくこれを見つけました。

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で望ましい「待機」効果が作成されます。

この回答の一部に触発されました。


7
便利な貢献、ありがとう!最新のSwift 3のアップデート:DispatchQueue.main.asyncAfter(deadline: when)
ロガレ2016

77
"+ 2"を "+ .seconds(2)"に置き換えることで、コードをもう少し速くすることができます。または、究極の迅速さのために、最初の行をドロップして、「deadline:when」を「deadline:.now()+ .seconds(2)」に置き換えることができます。
RenniePet 2017年

2
@OctavioAntonioCedeñoよろしくお願いします。これは本当にしばらくの間私を
悩ま

5
2017年3月12日現在も機能しています。:)
John Leonardo

3
文字通り、私の最も訪問されたSOの投稿。この投稿を実際に覚えたり、コード内の他の場所で見つけるよりも、この投稿を見つけるのは簡単です;)
barrylachapelle

154

私はGCDの1行表記が好きで、よりエレガントです。

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

また、iOS 10では、新しいTimerメソッド(ブロック初期化子など)があります。

(遅延アクションはキャンセルされる可能性があります)

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

ところで、覚えておいてください。デフォルトでは、タイマーはデフォルトの実行ループモードに追加されます。これは、ユーザーがアプリのUIを操作しているとき(たとえば、UIScrollViewをスクロールしているとき)にタイマーがフリーズする可能性があることを意味します。特定の実行ループモードにタイマーを追加することで、この問題を解決できます。

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

このブログ投稿で詳細を確認できます。


4
良いキャッチ!まだ見ていません。
julien_c 2016年

8
タイマーの比較とメインランループに関する免責事項に1つ追加してください!
マーティン

2
ナイスキャッチ!これはエンジニアリングです。
OnurŞahindur2017年

56

Swift 3.0以降に実装されている次の関数を試してください

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

使用法

delayWithSeconds(1) {
   //Do something
}

5
あなたは基本的にこの答えをコピーしただけですが、はいこれは良いです、ありがとう。
owlswipe 2016年

2
これをキャンセルするには?
Sourav Chandra

24

遅延については以下のコードを試してください

//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
}

1
最初の方法のディスプレイに「未解決の識別子「遅延」の使用」というエラーがある
Jerry Chong

5
このプログラマーはコードベースでヘルパーメソッドを使用しており、長い間使用してきました。したがって、遅延は、彼がしばらくの間使用しているコードであり、AppleのSDKの一部であることを知らないことでした。
Nick Perkins

4

1つの方法はDispatchQueue.main.asyncAfter、多くの人が答えたときに使用することです。

もう1つの方法は、を使用することperform(_:with:afterDelay:)です。詳細はこちら

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

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

1

// x秒後に関数を実行します

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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.