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

标签 macos swift swift2

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

登录成功后,我会显示我的主视图 Controller 。

如果用户已经登录(存储 token ),则应用程序必须直接使用主视图 Controller 启动。

我是 OSX 开发的新手,我用谷歌搜索了这种情况,但找不到任何东西。

所以我提出了我认为应该可行的方法。它有时有效,有时我会得到一个空白窗口。

在 Storyboard 中,我让主菜单和窗口 Controller 。我删除了主视图 Controller 的“包含”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!")
    }
}

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

此外,当它工作时,我登录,然后我想显示主视图 Controller :

func onLoginSuccess() {
    self.showViewController(NSStoryboard.mainViewController())
}

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

文档说 mainWindow 为 nil:

The value in this property is nil when the app’s storyboard or nib file has not yet finished loading. It might also be nil when the app is inactive or hidden.

但为什么 Storyboard在我启动时未完成加载或应用程序处于非事件状态?登录成功后,该应用肯定处于事件状态并在前台,主窗口始终为零。

我做错了什么?我怎样才能实现这个工作流程?或者我可以创建一个“父” View Controller ,将其连接到 Storyboard 中的窗口,并将登录或主视图 Controller 作为嵌套 View Controller 添加到其中。但我真的不喜欢添加一个什么也不做的 View Controller 。

我正在使用 XCode 7(测试版 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
    }
}

最佳答案

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

显然 NSApplication.sharedApplication().mainWindow 是一个与 Storyboard 中的主窗口不同的窗口。

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

然后我将应用程序委托(delegate)中的逻辑移至此 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()
    }
}

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

关于macos - 在应用程序启动时有条件地显示 NSViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31950410/

相关文章:

java - Mac Java崩溃错误

swift - 是否可以满足 Swift 协议(protocol)并添加默认参数?

ios - 默认参数值错误: "instance member cannot be used on type viewcontroller"

eclipse - 如何使用sbt-eclipse创建项目的Eclipse项目文件?

Swift 4 - avfoundation 屏幕和音频录制在 mac os 上使用 AVAssetWriter - 视频卡住

ios - 单击或点击时 View Controller 中的元素消失

ios - ViewController不符合协议(protocol) 'GIDSignInDelegate'

ios - 按下 “Edit” UITableViewRowAction 时无法切换到另一个 UIViewController

ios - Swift 2 迁移后,obj c 程序看不到 Swift 程序

linux - screen : how to turn on alternate screen?