登录失败导致未编码的转场?

5
我有一个应用程序,用户可以登录和注销(这是通过由Heroku托管的Parse服务器处理的,使用Parse框架)。
要登录,用户输入凭据,如果服务器验证它们,segue将它们移动到另一个视图控制器。退出登录会将用户从应用程序中注销,并将其segues返回到登录屏幕。这些都很好。
如果最初的登录凭据不正确,则会显示提示警报,提示用户重试,用户未登录(显然),并留在登录屏幕上。
但是,如果用户已登录,注销,然后按照此顺序输入不正确的凭据(而没有关闭模拟器),则会出现问题。不正确的凭据会弹出提示警报;单击“确定”关闭警报后,用户未登录,但视图已过渡到注销屏幕(其中有注销按钮...这应仅对已登录用户可用)。不存在将用户直接从登录移到注销屏幕的segue(无论是编码还是在故事板上)。

由于许多操作需要用户ID,而没有用户登录,因此没有任何操作起作用。我不知道为什么错误的登录会以那种方式移动VC,因为不存在可以执行该操作的segue。有一个segue可以在退出登录时反向移动,但没有朝那个方向的segue。

有人有任何想法吗?以下是相关的登录代码。

@IBAction func signInTapped(_ sender: UIButton) {
        UIApplication.shared.beginIgnoringInteractionEvents()

        PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in
            if user != nil{

                self.performSegue(withIdentifier: "signInSegue", sender: self)//if the sign in works    
            } else{

                if let errorString = (error! as NSError).userInfo["error"] as? String{

                    let errorMessage = errorString

                    self.displayAlert("Failed login", message: errorMessage)//this is the code run when the login fails, yet it somehow can sometimes segue to the other viewcontroller
                }   
            }
        })
}

这里是正在进行的步骤的逐步原理图。 用户从登录页面开始输入凭据 这将用户(现在已登录)转到一个 <code>tabbarViewController</code> 然后他们导航到另一个选项卡,那里有一个登出按钮 按下登出按钮会出现警报,点击是会将用户(现在已注销)转到原始屏幕 现在用户在登录界面。输入错误信息会弹出警报 警报出现。点击是关闭警报应该留在登录界面。但是,立即跳转到注销屏幕...这既不是编码也不是手动设置在故事板中
  1. 用户从登录页面开始输入他/她的凭据
  2. 这会使用户(现在已登录)转到一个tabbarViewController
  3. 然后他们导航到另一个选项卡,那里有一个注销按钮
  4. 按下注销按钮会引发一个警报,点击yes会使用户(现在已注销)回到原始屏幕
  5. 现在用户在登录屏幕上。输入错误信息会弹出一个警报
  6. 警报出现了。点击yes关闭警报应该让用户留在登录屏幕上。但是,此时立即跳转到了注销屏幕... 这既不是编码也不是手动设置在故事板中

我认为可能相关的随机事物: 有一个初始的segue,在第一个VC的viewDidAppear上调用(即登录屏幕),打开应用程序时会检查是否有用户登录。

if PFUser.current().username? != nil {
      //perform segue
}

这个转场将它们带到选项卡栏上的地图部分(与问题发生的注销页面不同)。
编辑:在“segue”到注销屏幕时,登录屏幕会下降(就像字面上一样,向下掉落,直到看不见,注销屏幕是可见的,这不是应用程序中任何转场的方式)。此外,当发生此过渡时,仅调用viewDidAppear代码,而不是viewDidLoad代码。
编辑2:我认为问题与视图层次结构有关。以下是登录函数的代码:
PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in

            if user?.username != nil{ 
                self.performSegue(withIdentifier: "signInSegue", sender: self) 
            } else{ //if everything in this code block is commented, the issue does not occur
                if let errorString = (error! as NSError).userInfo["error"] as? String{
                    let errorMessage = errorString
                    self.displayAlert("Failed login", message: errorMessage)
                }  
            }
        })

如果我在if语句的else部分注释掉所有内容,问题就不会发生。我认为发生的情况是显示了警报,点击“确定”关闭警报并将应用程序发送回最上层(也许我称呼它的方式不正确)的视图控制器,这些视图控制器中某个控制登出。我认为解决问题的好方法是在else代码中添加像self.present(homescreenVC)这样的内容,但我不知道如何做到这一点。

好的,所以 - 他们登出,这涉及到某种转场到登出代码,对吧?现在他们正在登录,但这不是转场的结果,而是一个IBAction,如果登录失败,则不会执行预期的signInSegue,而是弹出一个对话框,当它退出时,它会让你回到之前的注销控制器,在那里你进入了弹出对话框的代码。似乎认为这样做是正确的。还不确定正确的解决方案是什么,但想到的是... - clearlight
如果你不展示更多的代码或者非常清晰、甚至是图解的状态/流程,我们很难在抽象的层面上帮助你理解问题。请详细描述你从哪个状态/控制器转移到了哪个状态/控制器等相关信息。 - clearlight
https://dev59.com/SGcs5IYBdhLWcg3w0HIa#15839298 - clearlight
https://dev59.com/rGox5IYBdhLWcg3wIQ_3 - clearlight
1
我之前在自己的代码中也曾经遇到过关于segue的奇怪问题。这可能是一个真正的挑战和麻烦。阅读一些我发布的内容,了解unwind并尝试熟悉segue的基本机制,这应该有助于您诊断和解决问题。可能需要一些时间,但这就是事情的进展方式。 - clearlight
显示剩余11条评论
1个回答

0
@IBAction func signInTapped(_ sender: UIButton) {
    UIApplication.shared.beginIgnoringInteractionEvents()

    PFUser.logInWithUsername(inBackground: userNameTextField.text!, password: passwordTextField.text!, block: { (user, error) in
        if error != nil {
             if let errorString = (error! as NSError).userInfo["error"] as? String{

                let errorMessage = errorString

                self.displayAlert("Failed login", message: errorMessage)
               }
        } 
        else {
            self.performSegue(withIdentifier: "signInSegue", sender: self)

            }   
        })
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接