swift - 我怎样才能摆脱 View Controller 中的关闭?

标签 swift firebase viewcontroller

尝试找到一些有关它的信息,但我找不到。

所以当我点击登录时我得到了这个代码。

@IBAction func checkLogin(_ sender: UIButton) {

    let email = userEmail.text!
    let password = userPassword.text!

    if email == "" || password == "" || !email.isValidEMail {
        userEmail.shake()
        userPassword.shake()
        return
    }

    Auth.auth().signIn(withEmail: email, password: password, completion: {(user, error) in

        var collectError = ("","")

        if error != nil {
            collectError = ("Error", (error?.localizedDescription)!)
            self.alertMsg(title: collectError.0, message: collectError.1)
            return
        }

        if !(user?.isEmailVerified)! {
            collectError = ("Error", "Your account is not verified! Confirm your account from email!")
            return
        }

        print("OK, User Authentificated: \(Auth.auth().currentUser?.email)")

        // DispatchQueue.main.async { }
        //return

        self.navigationController?.popViewController(animated: true)
        //self.dismiss(animated: true, completion: nil)

    })

我有第一个 View Controller ,它为用户提供登录或注册选项。所以我选择例如登录。尝试登录,它会让我返回到第一个 View Controller ,如果用户登录其中隐藏第一个 View Controller ,我会得到验证 firebase 监听器,但是当我单击 profile.storyboard 中的注销时,它会立即向我显示第一个登录 Controller 。当我尝试再次登录时,没有任何反应,为什么我不知道

我知道我需要使用导航返回功能

self.navigationController?.popViewController(animated: true)

如果我想隐藏 View 控件,还有按钮

self.dismiss(animated: true, completion: nil)

最佳答案

所以,当你的 main.storyboard 的根 Controller 被加载或将/确实出现时,你正在尝试检查授权,如果用户未授权,你将呈现登录 Controller ,对吗?

在您的情况下,您需要至少有两个独立的导航堆栈(我们将它们称为主堆栈和登录堆栈)

这意味着当用户未授权时应显示(而不是推送)您的登录 View Controller ,并在用户成功登录或取消注册后应关闭(而不是弹出)。

我的项目中有几乎相同的注册流程。我将尝试在下面的示例代码中解释它

class MainController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        //detecting the firebase, just a custom bool var
        if !isAuthorized {
            //call the method to present login controller
            presentLoginController()
        }
    }

    func presentLoginController(){
        let segue = UIStoryboard(name: "Login", bundle: nil)

        if let loginNavigationController = segue.instantiateInitialViewController() {

            self.present(loginNavigationController, animated: true, completion: nil)
        }

    }


}

现在您将看到登录 Controller 。所以这将创建第二个导航堆栈(登录堆栈)。这将是一个单独的导航,其中根 Controller 是登录导航 Controller (Login.storyboard 中的初始 Controller )。对于此堆栈中的任何 Controller ,如果您调用 navigationController?.popToRootViewController,它将带您到登录堆栈中的根 Controller 。不要在这里使用 self.dismiss(animated: true, succession: nil) ,它可能会破坏你的导航

因此,当用户登录或授权完成或取消时,您需要显示一个主 Controller (主堆栈),您可以在其中再次检查 isAuthorized。这是您可以实现的方法:

func navigateToTheRoot(){
        //this code will dismiss all modal controllers that was presented
        UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: false, completion: nil)

        //accessing to the appDelegate
        let appDelegate = UIApplication.shared.delegate as? AppDelegate

        //now this will return your app to the main controller
        if let navigationController = appDelegate?.window?.rootViewController as? UINavigationController {
            navigationController.popToRootViewController(animated: true)
        }
 }

在单独的导航堆栈中显示的任何 Controller 中调用此方法(例如取消注册,在单击登录堆栈中的“X”按钮后调用此方法)。

如果您的配置文件 Controller 有一个导航 Controller 作为 Profile.storyboard(第三个堆栈 - 配置文件堆栈)的首字母,那么您需要以与我用于登录 Controller 的相同方式呈现它。在这种情况下,要注销,您需要从配置文件堆栈中的任何 Controller 调用方法navigateToTheRoot()以显示主 Controller 。

否则,如果您的个人资料 Controller 只是一个没有附加导航的 Controller ,并且它是从主堆栈中的任何其他 Controller 推送的,那么您只需调用以下命令:

self.navigationController?.popToRootViewController(animated: true)

您将看到 main.stack 的根 Controller

无论之前已呈现或推送了多少个 Controller ,都可以从任何其他 Controller 到达 Main.storyboard 的根目录:

  • 如果您的 Controller 已显示(不在主堆栈中)并且位于附加导航堆栈中,请使用我描述的 navigatorToTheRoot() 方法

  • 如果您的 Controller 被推送(push segues 或 navigationController?.pushViewController 以编程方式使用),请使用 navigationController?.popToRootViewController

  • 如果您的 Controller 已显示(模态)并且它只是没有导航的单个 Controller ,只需调用 self.dismiss(animated: true, succession: nil)

希望对您有帮助。有需要可以问我

附注在您的注册 Controller 中(当用户单击“Зарегистрироваться”时显示)有一个小错误“Зарегестрироваться”。 Удачи! ;)

关于swift - 我怎样才能摆脱 View Controller 中的关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45902674/

相关文章:

swift - 将字符串转换为 double 给出 nil

ios - Swift xCode 6.4 - 在第二个 View Controller 中使用由 TableView Controller 生成的变量

ios - 如何从 View Controller 传递数据?

swift - 如何确定 Xcode 中最后一个激活的 UITextField

ios - 确保在 Info.plist 新 GoogleSignIn IOS 版本中设置 GIDClientID

Swift:从 [Int: UIView]() 访问 UIView 子级

ios - swift 4 : Presenting ViewControllers with a UIView as the frame

firebase - Google Cloud Functions-警告避免嵌套 promise 答应/禁止嵌套

android - Firebase 云消息传递 Gradle 设置

firebase - Firestore HTTP 失眠查询 : Stream error in the HTTP/2 framing layer