ShouldPerformSegue触发两次:登录按钮需点击两次才跳转的问题求助
解决登录按钮首次点击不跳转的问题
这个问题的核心原因很明确:你的AuthService.instance.loginUser是异步网络请求,当你点击按钮时,系统会先执行shouldPerformSegue方法,但此时异步请求还没返回结果,successLogin仍然是初始的false,所以第一次点击会触发提示框。等第一次点击后,异步请求完成,successLogin被设置为true,第二次点击时shouldPerformSegue就返回true,才能完成跳转。
要解决这个问题,我们需要把segue的触发逻辑从系统自动判断改成手动触发,也就是等异步登录请求明确返回成功后,再主动调用跳转方法。具体步骤如下:
步骤1:调整故事板中的Segue设置
- 先删除按钮到ViewController B的直接segue(就是你之前从按钮拖到B创建的那个)
- 重新创建segue:从ViewController A的顶部导航栏(或者视图控制器本身)拖到ViewController B,给这个segue设置identifier为
homeSegue(保持和之前一致)
步骤2:修改ViewController A的代码
我们不再依赖successLogin变量和shouldPerformSegue方法,而是在登录成功的回调里直接触发跳转,同时做一些优化:
@IBAction func SignInButtonPressed(_ sender: Any) { // 简化空值判断逻辑 guard let email = username.text, !email.isEmpty else { self.displayAlertView(title: USER_LOGIN_FAILED_TITLE, message: USER_LOGIN_FAILED_MESSAGE) return } guard let pass = password.text, !pass.isEmpty else { self.displayAlertView(title: USER_LOGIN_FAILED_TITLE, message: USER_LOGIN_FAILED_MESSAGE) return } // 禁用按钮,防止用户重复点击请求 if let loginButton = sender as? UIButton { loginButton.isEnabled = false } // 使用[weak self]避免循环引用 AuthService.instance.loginUser(email: email, password: pass) { [weak self] success in // 恢复按钮可点击状态 if let loginButton = sender as? UIButton { loginButton.isEnabled = true } guard let self = self else { return } if success { // 登录成功,手动触发segue跳转 self.performSegue(withIdentifier: "homeSegue", sender: self) } else { self.displayAlertView(title: USER_LOGIN_FAILED_TITLE, message: USER_LOGIN_FAILED_MESSAGE) } } } // 可以删除shouldPerformSegue方法了,因为现在是手动控制跳转时机
额外优化建议
- 加入
[weak self]是为了避免ViewController在异步请求未完成时被销毁导致的循环引用 - 禁用按钮可以防止用户在请求过程中多次点击,避免重复发起登录请求
- 空值判断用
!email.isEmpty比username.text != ""更符合Swift的写法
内容的提问来源于stack exchange,提问作者chirag90
相关产品推荐
相关产品推荐

