2017-06-30 14 views
1

ユーザーが何回押したかに応じて0.5秒後に関数を呼び出すUIControlがあります。 (例:1を押すとf1()、2がf2()を押す、3がf3()を押す)Swift 3のメインスレッドで時間遅延の後に関数を呼び出す方法はありますか?

基本的には、ユーザーがコントロールを押したときにタイマーを設定する必要があります。コントロールが0.5秒間押されていない場合は、ダイアログを作成します。私はDispatchQueueを使用しようとしましたが、ダイアログを作成する時点になると数秒かかります。私はそれがメインスレッドの代わりに同時に呼び出されているからだと思います(貧弱な用語があれば謝罪します)。

self.operationQueue.cancelAllOperations() //To cancel previous queues 
self.mainAsyncQueue = DispatchQueue(label: "bubblePressed" + String(describing: DispatchTime.now()), qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent) 

let time = DispatchTime.now() 
self.currentTime = time 

self.mainAsyncQueue!.asyncAfter(deadline: time + 0.5){ 
    guard self.currentTime == time else { 
    return 
    } 

    let tempOperation = BlockOperation(block:{ 
    self.displayDialog() 
    }) 
    self.operationQueue.addOperation(tempOperation) 
} 

operationQueuemainAsycQueueは、それがより速くロードされるようにどのように私はメインスレッドで私の機能displayDialog()を呼び出すことができます

self.currentTime = DispatchTime.now() 
self.operationQueue = OperationQueue() 

としてviewDidLoadで定義されていますか?

+1

問題は、あなたが他のスレッドでUIを更新しようとしているということですメインスレッドよりも。操作キューは必要なく、 'mainAsyncQueue'を作成する必要もありません。このコードでは、必要なのはメインキューだけです。 – Rob

答えて

2

私はそれが複雑に近い場所にある必要はないと思います。 Timerを使用することができます。

class MyClass: UIViewController { 

    var tapCount = 0 
    var tapTimer: Timer? 

    @IBAction tapped(_ sender: Any) { 
     if tapCount < 3 { 
      tapCount += 1 
      tapTimer?.invalidate() 
      tapTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { (timer) in 
       switch (self.tapCount) { 
        case 1: 
         self.f1() 
        case 2: 
         self.f2() 
        case 3: 
         self.f3() 
        default: 
         // Hmm, shouldn't happen 
       } 
       self.tapCount = 0 
      }) 
    } 
} 

タイマーは、デフォルトではメインキューにスケジュールなので、メインキューに何かを派遣する必要はありません、具体的

+0

ありがとう:) 'timer.invalidate'は' f1' 'f2'' f3'関数が複数回呼び出されるのを防ぐために必要なものです! –

3

は、質問のタイトルに基づいて、答えは:FUNC以下

let deadlineTime = DispatchTime.now() + .seconds(1) 
DispatchQueue.main.asyncAfter(deadline: deadlineTime) { 
    //update UI here 
    self.displayDialog() 
} 

または

DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
    self.displayDialog() 
} 
0

使用して、それがメインスレッドでFUNCを実行し、他のアクションは、この実行中に実行しません。

DispatchQueue.main.async { 
    self.displayDialog()     
} 
+0

しかし、もしOPがadevのように最初の 'asyncAfter'をメインキューに渡しただけであれば、この内部の' async'呼び出しはまったく必要ありません。 – Rob

関連する問題