【问题标题】:performSegue not working since update to Xcode 9 (and iOS 11)自更新到 Xcode 9(和 iOS 11)后 performSegue 无法正常工作
【发布时间】:2023-03-12 09:32:01
【问题描述】:

在我的应用程序中,我有一个启动画面,用于检查用户是否已使用 Facebook 登录。如果他不是,则启动屏幕将登录屏幕推送到导航堆栈。如果用户已登录,则启动屏幕也会推送登录屏幕,但会在登录屏幕的 viewDidAppear 上调用一个推送主应用屏幕的方法。

因此,当用户登录时,我应该在我的应用程序上看到以下视图控制器堆栈:

SplashViewController > LoginViewController > MainViewController.

此流程在 iOS 9 和 iOS 10 上运行没有问题。

但是,自从我升级到 iOS 11 后,此流程停止工作。

现在,如果用户登录了主视图控制器没有出现,只有登录视图控制器仍然可见。我检查了确实调用了对主应用屏幕执行Segue的调试器。

有两个奇怪的细节。首先是这个登录视图控制器上的按钮不再起作用(有一个按钮从 FacebookLogin SDK 调用 Facebook 登录流程)。

第二个是,如果我去 Xcode 并点击“Debug View Hierarchy”按钮,而 Xcode 正在处理和创建视图层次结构,主视图控制器突然出现在我的应用程序上。

似乎主视图控制器正在被推送,但它的视图没有被呈现;所以 LoginViewController 上的 segues 不再起作用了。然而,按下“Debug View Hierarchy”似乎会触发一些更新视图层次结构的东西。

我正在使用 Xcode 9.0.1。这个问题在 Xcode 模拟器和我的 iPad Mini 2 上都发生,它当前运行的是 iOS 11.0.3。

谢谢。

【问题讨论】:

  • 我似乎有同样的问题,但我使用的是 KYDrawerController。如果我删除了 KYDrawerController,那么它可以正常工作(除了我丢失了我的菜单)。

标签: ios11 xcode9


【解决方案1】:

我不知道发生这种情况的确切原因,但我能够通过以下方式解决此问题。

在 SplashViewController 上,我将 direct 转场调用到登录视图控制器,这将在 viewWillAppear() 方法上调用另一个转场,我强制在主队列上执行转场:

// SplashViewController
struct Identifier {
    static let login = "Login"
    static let direct = "Direct"
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    login()
}

func login() {
    // If there already exists a Facebook token we try to login directly.
    if let accessToken = AccessToken.current {
         bm.login(facebookToken: accessToken.authenticationToken, completion: { (error, user) in
            guard error == nil else {
                self.performSegue(withIdentifier: Identifier.login, sender: self)
                return
            }
            // This call on the main queue wasn't needed on iOS 10
            DispatchQueue.main.async {
                self.performSegue(withIdentifier: Identifier.direct, sender: self)
            }
        })
    } else {
        performSegue(withIdentifier: Identifier.login, sender: self)
    }
}

然后在 LoginViewController 上:

// LoginViewController
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if direct {
        // Without calling the previous segue on the main queue this 
        // segue would be called but the pushed view controller's 
        // view would not appear on the screen until a refresh event 
        // was triggered.
        self.performSegue(withIdentifier: Identifier.direct, sender: nil)
    }
}

【讨论】:

  • 感谢 Felipe,你救了我的命!我没有找到任何有关此问题的文档,但我在 ios 11 上遇到了完全相同的问题。这应该记录在某个地方。
猜你喜欢
  • 1970-01-01
  • 2018-12-06
  • 2019-12-26
  • 2011-11-23
  • 1970-01-01
  • 2017-10-20
  • 2015-12-17
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多