web-dev-qa-db-ja.com

Swiftビューがウィンドウ階層にないUIAlertControllerを表示しようとします(TWTRShareEmailViewControllerの後に表示されます)

アプリのサインアッププロセスでTwitterログインを使用しています。そして、私はユーザーのメールを求めています。取得したら、UIAlertControllerを提示します。

これが私のコードです:

func askForTWMail(){
    if (Twitter.sharedInstance().session() != nil) {
        let shareMailVC=TWTRShareEmailViewController(completion: {(mail:String!, error:NSError!) in
            if (mail != nil) {
                print("GOT MAIL: \(mail)")
                self.gotMail()
            }else{
                print("MAIL VC ERROR: \(error)")
            }
        })
        println("PRESENT MAIL VC")
        self.presentViewController(shareMailVC, animated: true, completion: nil)
    }else{
        println("User not logged in")
    }
}

func gotMail(){
    var alertController=UIAlertController(title: "Some title", message: "Some message", preferredStyle: UIAlertControllerStyle.Alert)
    var okAction=UIAlertAction(title:"Yes", style: UIAlertActionStyle.Default) {
    UIAlertAction in
    //some action
    }
    var cancelAction=UIAlertAction(title:"No", style: UIAlertActionStyle.Cancel){
    UIAlertAction in
    //some action
    }
    alertController.addAction(okAction)
    alertController.addAction(cancelAction)
    self.presentViewController(alertController, animated: true, completion: nil)                
}

しかし、私はこのエラーを受け取ります(TWTRShareEmailViewControllerが閉じられていないためと思います):

警告:ビューがウィンドウ階層にないxViewControllerにUIALertControllerを提示しようとしています!

これをどのように書くべきかについてのアイデアはありますか?サインアッププロセスを続行してTWTRShareEmailViewControllerを提示できるようにUIAlertControllerが解任されたことを確認するにはどうすればよいですか? TWTRShareEmailViewControllerに関連するデリゲートメソッドについては知りません。

どんな助けでもありがたいです。ありがとう。

15
Marie Dm

解決策が見つかりました ここ 。私はおそらくそれを間違っていますが、そうでない場合はAppleバグかもしれません。回避策はUIAlertControllerの表示を遅らせることです:

dispatch_async(dispatch_get_main_queue(), ^{
    self.presentViewController(alertController, animated: true, completion: nil)
})

[〜#〜] edit [〜#〜]:別の回避策を見つけました(ここに置いた解決策はもう使用していません)。 TwitterログインもVC間の私の移行を壊していたので、これを変更する必要がありました。

私は今、特定のUIViewControllerTWLoginVCのような名前を付けました)を呼び出します。ここでは、Twitterのログインやその他すべてのことを行います。ビューが真っ黒なので、ユーザーはプロセスが実際には別のVCで実行されていることを確認できません(彼はログインしたいTwitterユーザーをピックアップする必要があります)。私はあなたができると思いますまた、背景がはっきり見えるようにすると、さらに目立たなくなります。

このビューコントローラーを呼び出して閉じても、遷移は適用されず、問題は発生しません。


[〜#〜] edit [〜#〜]Swiftの更新:

DispatchQueue.main.async{
     self.present(alertController, animated: true, completion: nil)
}
31
Marie Dm

Swift 3の更新された回答は、Marie Dmの回答に基づいてXcode 8でテストされています。

DispatchQueue.main.sync {
     self.present(alertController, animated: true, completion: nil)
}
5
Asdrubal