尝试找到一些有关它的信息,但我找不到。
所以当我点击登录时我得到了这个代码。
@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/