Swift - 从完成块中解除视图控制器

Posted

技术标签:

【中文标题】Swift - 从完成块中解除视图控制器【英文标题】:Swift - dismissing view controller from within a completion block 【发布时间】:2016-03-20 22:15:36 【问题描述】:

简单的问题。如果我在完成块内 - 例如使用 firebase 的 facebook 登录 ...并且登录成功。如果我想从完成块中关闭当前视图控制器(登录视图控制器),我是否需要返回主队列来执行此操作。我假设登录完成块是在后台线程上完成的,并且对 UI 的任何更改(即关闭当前视图控制器)都应该在主线程上完成......这里的最佳实践是什么......或者我错过了什么?

@IBAction func facebookLoginTapped(sender: AnyObject) 

    //
    let ref = Firebase(url: "https://XXXX.firebaseio.com")
    let facebookLogin = FBSDKLoginManager()
    facebookLogin.logInWithReadPermissions(["email"], fromViewController: self, handler:  (facebookResult, facebookError) -> Void in
        if facebookError != nil 
            print("Facebook login failed. Error \(facebookError)")
         else if facebookResult.isCancelled 
            print("Facebook login was cancelled.")
         else 
            //successfully logged in
            //get facbook access token
            let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
            //use access token to authenticate with firebase
            ref.authWithOAuthProvider("facebook", token: accessToken,
                withCompletionBlock:  error, authData in
                    if error != nil 
                        print("Login failed. \(error)")
                     else 
                        //authData contains
                        print("Logged in! \(authData)")

                        //pop loginvc back to uservc - DO I NEED TO GET MAIN THREAD HERE BEFORE DISMISSING VIEW CONTROLLER
                        self.dismissViewControllerAnimated(true, completion: nil)
                    
            )
        
    )

【问题讨论】:

与我关于 performSegue 的回答相同的问题:***.com/questions/32292600/… 你必须在主线程上做。 【参考方案1】:

您应该“弹出”回主线程来执行此操作。它非常简单,只需包装

self.dismissViewControllerAnimated(true, completion: nil) 这样...

Swift 2.x

dispatch_async(dispatch_get_main_queue())
    self.dismissViewControllerAnimated(true, completion: nil)

Swift 3 4 & 5:

DispatchQueue.main.async 
      self.dismiss(animated: true, completion: nil)

【讨论】:

如果从 DispatchQueue.global(qos: .background).async 调用则不起作用 您需要在主线程上进行 UI 更新。不要从后台线程调用它 但我正在使用 DispatchQueue.main.async 我不明白,你能打开一个问题添加你的代码并分享链接,我会看看它

以上是关于Swift - 从完成块中解除视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中使用警报视图解除 segue?

关闭模式视图控制器偶尔冻结应用程序,swift 3

解除视图控制器动画:完成:在 iOS 8 上

Swift 3 - 调用准备 segue 时视图不更新

为啥在模态视图控制器被解除后 CAGradientLayer 从视图中删除

当模态视图控制器被解除时如何调用函数