【问题标题】:Swift - dismissing view controller from within a completion blockSwift - 从完成块中解除视图控制器
【发布时间】: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)
                    }
            })
        }
    })
}

【问题讨论】:

标签: ios swift login uiviewcontroller closures


【解决方案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
  • 我不明白,你能打开一个问题添加你的代码并分享链接,我会看看它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多