尝试呈现其视图不在视图层次结构中的 UITabBarController - Firebase,Swift

Posted

技术标签:

【中文标题】尝试呈现其视图不在视图层次结构中的 UITabBarController - Firebase,Swift【英文标题】:Attempt to present UITabBarController whose view is not in the view hierarchy - Firebase, Swift 【发布时间】:2016-04-10 21:23:39 【问题描述】:

我正在开发应用的登录系统,当用户注册时,我希望它直接“进入”应用。意思是,回到登录屏幕,然后重定向“进入”应用程序,或者提示注册后登录。期望的结果是使用以下代码:

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //The disallowed character set is the inverse of the allowed characters
    disallowedUsernameCharacters = allowedUsernameCharacters.invertedSet

    //Set the delegates
    confirmPassTextField.delegate = self
    passwordTextField.delegate = self
    usernameTextField.delegate = self
    emailTextField.delegate = self

    //Observe authentication events, if the authentication is successful, perform the segue
    ref.observeAuthEventWithBlock  (authData) -> Void in
        if authData != nil 

            //Use standard defaults
            let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
            //Store the uid
            prefs.setObject(authData.uid as String, forKey: "UID")

            self.performSegueWithIdentifier(self.successfulSignUp, sender: nil)
        
    

如果用户在其中注册并通过身份验证,它将执行对 UITabBarController 的 segue,其中包含应用程序本身的 5 个选项卡/视图。这工作正常,但我收到 警告:尝试显示其视图不在窗口层次结构中!

通过一些研究,这似乎是人们得到的一个相当普遍的警告。但是,我想修复它,以便应用程序的所有部分都能按预期运行。我发现有些人建议把代码部分:

//Observe authentication events, if the authentication is successful, perform the segue
ref.observeAuthEventWithBlock  (authData) -> Void in
            if authData != nil 

                //Use standard defaults
                let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
                //Store the uid
                prefs.setObject(authData.uid as String, forKey: "UID")

                self.performSegueWithIdentifier(self.successfulSignUp, sender: nil)
            

viewWillAppear 方法内部,因为在调用 segue 时当前视图可能不在层次结构中,但我认为这不是解决方法,因为它不是立即调用,仅在身份验证事件上 - 我也不想把它放在这里,因为我的理解是根据事件频繁调用此方法。

我还发现有些人在不同的线程上执行它,类似于:

dispatch_async(dispatch_get_main_queue(), 
            self.performSegueWithIdentifier(self.successfulSignUp, sender: nil)
)

但我在想的是,触发 segue 的“注册”视图控制器不是最顶层的视图控制器,这就是发生错误的原因。另外,我读到一个解决方案是嵌入一个 UINavigationController,如果这是解决方案......有没有人知道如何做到这一点的任何资源?如果有不同的解决方案,它会是什么?任何帮助都会很棒!干杯。

编辑:

我的故事板如下所示:

入口点是 UITabBarController,在 AppDelegate.swift 中我通过检查用户默认值中的布尔值来检查用户是否已登录,如果他们没有登录,我将 rootController 更改为LoginViewController,用户可以在其中登录,它将继续到 UITabBarController,或者他们可以注册,并且在成功注册后,它将继续到 UITabBarController - 这是我收到警告的地方

【问题讨论】:

performSegueWithIdentifier 必须在主线程上完成。添加dispatch_async是正确的。 我仍然收到 dispatch_async 警告 【参考方案1】:

我还没有弄清楚为什么,一旦我知道了,我会更新答案,但为了解决这个问题,我输入了self.performSegueWithIdentifier(self.LoginToFeed, sender: nil)

到一个单独的函数中

func callSegue() 
    self.performSegueWithIdentifier(self.LoginToFeed, sender: nil)

并从块中调用函数,警告不再出现

【讨论】:

以上是关于尝试呈现其视图不在视图层次结构中的 UITabBarController - Firebase,Swift的主要内容,如果未能解决你的问题,请参考以下文章

尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController

尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController

尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController

警告:尝试在其视图不在窗口层次结构中的 * 上呈现 * - swift

尝试呈现其视图不在视图层次结构中的 UITabBarController - Firebase,Swift

尝试呈现其视图不在窗口层次结构中的 UIAlertController (Swift 3/Xcode 8)