2017-03-04 13 views
2

Swift 3、Xcode 8.2を使用しています。Swift 3 - 非同期ジョブ後にView Controllerを解除する

私はボタンがあるビューコントローラを持っています。ボタンを押すと、以下のbuttonPressed機能が実行されます。それは、回転するギアの動作インジケーターがポップアップするまで数秒かかる非同期ジョブを開始します。ジョブが終了したら、アクティビティインジケータを消して、View Controllerを元のVCに戻すようにします。

func buttonPressed() { 

    // Set up some stuff here 
    ... 

    // this code block here is to asynchronously run the processing job 
    // while the activity indicator gear spins 
    self.displaySpinningGear() 
    DispatchQueue.main.async { 
     self.doSomeJobProcessing() 
    } 
    self.dismiss(animated: true, completion: nil) 

    // also dismiss the camera view 
    self.presentingViewController?.dismiss(animated: true, completion: nil) // error here 
} 

はしかし、私はその最後の文にエラーが発生します。

[アサート] 移行すでにながら、プレゼンテーションコントローラを解任しようとしています。 (< _UIAlertControllerAlertPresentationController:0x109e3b190>) 2017年3月3日21:37:56.833899 EOBリーダー[27710:6869686] [アサート] transitionViewForCurrentTransitionは、プレゼンテーションコントローラ がプレゼンテーション中に却下された、設定されていませんか? (< _UIAlertControllerAlertPresentationController:0x109e3b190>)

任意の助けを大幅に高く評価されるだろう。

答えて

2

これらのトランジションを一度に実行します。

if let viewController = presentingViewController { 
    // This block will dismiss both current and a view controller presenting current. 
    viewController.dismiss(animated: true, completion: nil) 
} else { 
    // This block will dismiss only current view controller 
    self.dismiss(animated: true, completion: nil) 
} 

2つの移行操作を同時に実行することはできません。

  • ソースコードでは、現在のビューコントローラをアニメーションで終了します。アニメーションは、通常、操作を完了するのに約0.25秒かかります。

  • 今、次の行で、現在のビューコントローラを表示している(**)ビューコントローラを閉じようとしています。 (あなたのケースでは、(**)ビューコントローラは他のビューコントローラでも表示されます。)したがって、秒数/ミリ秒(**)の間にView Controllerもアニメーションで自己解約しようとします。

  • 現在のところ、現在のビューコントローラが閉じられており、(**)ビューコントローラもディスマウント操作を開始します。したがって、両方の操作は、メインの実行スレッド上で互いに競合します。問題が生じたら、あなたは直面しています。あなたがここに他のビュー/コントローラ遷移動作を設定した場合

また、ここではブロック

self.doSomeJobProcessing() 

共有のためにあなたのコードを共有しています。

+0

ありがとうございました!これは私にとって完璧に機能しました。あなたがしていたことの背後にある根拠を私に説明してもらえますか?私はなぜ私が問題を抱えているのかを知ろうとしています。 – noblerare

+0

私の答えが更新されました。まだ質問があれば教えてください.... – Krunal

+0

あなたの編集をありがとうございます! – noblerare

0

非同期をディスパッチすると、通常、UIブロックを防ぐためにバックグラウンドスレッドにディスパッチすることに注意してください。すべてのオンスクリーン(UI)コンポーネントは、メインスレッド上で変更する必要があります。したがって、メインスレッドから進行スピナーを開始し、重い吊り上げをバックグラウンドにディスパッチしてから、メインスレッドに再ディスパッチします。 this.dismissviewcontroller:animated

まもなくコードで更新されます。

関連する問題