在应用程序启动时有条件地显示NSViewController

Ixx*_*Ixx 10 macos swift swift2

我正在开发一个OSX应用程序,如果用户尚未登录,我首先显示一个登录/注册窗口.

登录成功后,我会显示我的主视图控制器.

如果用户已登录(存储了令牌),则应用程序必须直接使用主视图控制器启动.

我是OSX开发的新手,我用Google搜索了这种情况,却找不到任何东西.

所以我提出了我认为应该工作的东西.它有时有效,有时我会得到一个空白的窗口.

在故事板中,我让主菜单和窗口控制器.我删除了"包含"segue到我的主视图控制器.

在AppDelegate中,我把它放在:

func applicationDidFinishLaunching(aNotification: NSNotification) {

    if loggedIn {
        self.showViewController(NSStoryboard.mainViewController())

    } else {
        let loginController = NSStoryboard.loginViewController()
        loginController.delegate = self
        self.showViewController(loginController)
    }
}

private func showViewController(viewController: NSViewController) {
    if let mainWindow = NSApplication.sharedApplication().mainWindow {
        mainWindow.contentViewController = viewController

    } else {
        print("Error: No main window!")
    }
}
Run Code Online (Sandbox Code Playgroud)

大约一半时间窗口是空的,我在控制台中看到"错误:没有主窗口!".我想也许我可以使用,applicationDidBecomeActive但这基本上被称为前景,这不是我需要的.

此外,它工作的时间,我登录,然后我想显示主视图控制器:

func onLoginSuccess() {
    self.showViewController(NSStoryboard.mainViewController())
}
Run Code Online (Sandbox Code Playgroud)

在这里我也得到"错误:没有主窗口!" (总是)没有任何反应.

文档说下面是关于mainWindownil:

当应用程序的故事板或nib文件尚未完成加载时,此属性中的值为nil.当应用程序处于非活动状态或隐藏状态时,它也可能是零.

但是为什么故事板在我启动时没有完成加载或应用程序处于非活动状态?在登录成功时,应用程序肯定是活动的并且在前台,主窗口始终为零.

我究竟做错了什么?我该如何实现这个工作流程?或者,我可以创建一个"父"视图控制器,将其连接到故事板中的窗口,并将登录或主视图控制器添加为嵌套视图控制器.但是不要真的喜欢添加一个什么都不做的视图控制器.

我正在使用XCode 7(beta 4),Swift 2,OSX 10.10.4

编辑:

NSStoryboard方法来自扩展,它看起来像这样:

extension NSStoryboard {

    private class func mainStoryboard() -> NSStoryboard { return NSStoryboard(name: "Main", bundle: NSBundle.mainBundle()) }
    private class func signupStoryboard() -> NSStoryboard { return NSStoryboard(name: "LoginRegister", bundle: NSBundle.mainBundle()) }

    class func mainViewController() -> ViewController {
        return self.mainStoryboard().instantiateControllerWithIdentifier("MainViewController") as! ViewController
    }

    class func loginViewController() -> LoginViewController {
        return self.signupStoryboard().instantiateControllerWithIdentifier("LoginViewController") as! LoginViewController
    }

    class func registerViewController() -> RegisterViewController {
        return self.signupStoryboard().instantiateControllerWithIdentifier("RegisterViewController") as! RegisterViewController
    }
}
Run Code Online (Sandbox Code Playgroud)

Ixx*_*Ixx 5

为了把我们在评论中找到的解决方案作为答案:

显然NSApplication.sharedApplication().mainWindow是与情节提要中的主窗口不同的窗口。

因此,我创建了一个NSWindowController子类,并使用身份检查器将其分配给情节提要中的窗口。

然后,我将应用程序委托中的逻辑移到了此NSWindowController。看起来像这样:

class MainWindowController: NSWindowController, LoginDelegate {

    override func windowDidLoad() {

        if loggedIn {
            self.onLoggedIn()
        } else {
            let loginController = NSStoryboard.loginViewController()
            loginController.delegate = self
            self.contentViewController = loginController
        }
    }

    func onLoggedIn() {
        self.contentViewController = NSStoryboard.mainViewController()
    }

    func onLoginSuccess() {
        self.onLoggedIn()
    }
}
Run Code Online (Sandbox Code Playgroud)

*感谢Lucas Derraugh为我指出正确的方向!