在应用程序启动时有条件地显示 NSViewController
Conditionally showing NSViewController at app launch
我正在开发一个 OSX 应用程序,如果用户尚未登录,我会首先显示 login/register window。
登录成功后,我显示我的主视图控制器。
如果用户已经登录(存储令牌),则应用程序必须直接使用主视图控制器启动。
我是 OSX 开发的新手,我用谷歌搜索了这种情况,但找不到任何东西。
所以我提出了我认为应该可行的方法。它有时有效,有时我得到一个空白 window.
在故事板中,我让主菜单和 Window 控制器。我删除了 "contains" 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!")
}
}
大约一半的时间 window 是空的,我在控制台中看到 "Error: No main window!"。我想也许我可以使用 applicationDidBecomeActive
但这基本上是在前台调用的,这不是我需要的。
此外,它工作的时间,我登录,然后我想显示主视图控制器:
func onLoginSuccess() {
self.showViewController(NSStoryboard.mainViewController())
}
这里我也得到 "Error: No main window!"(总是)但没有任何反应。
文档说 mainWindow
为零:
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.
但为什么故事板在我启动时未完成加载或应用程序处于非活动状态?并且在登录成功时,该应用程序绝对处于活动状态并且在前台并且主要 window 始终为零。
我做错了什么?我怎样才能实施这个工作流程?或者,我可以创建一个 "parent" 视图控制器,将其连接到情节提要中的 window,然后将登录或主视图控制器作为嵌套视图控制器添加到其中。但是我真的不喜欢添加一个什么也不做的视图控制器。
我正在使用 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
与故事板中的主要 window 不同 window。
因此,我使用身份检查器创建了一个 NSWindowController
子类并将其分配给故事板中的 window。
然后我将我在应用程序委托中的逻辑移到了这个 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 为我指明了正确的方向!
我正在开发一个 OSX 应用程序,如果用户尚未登录,我会首先显示 login/register window。
登录成功后,我显示我的主视图控制器。
如果用户已经登录(存储令牌),则应用程序必须直接使用主视图控制器启动。
我是 OSX 开发的新手,我用谷歌搜索了这种情况,但找不到任何东西。
所以我提出了我认为应该可行的方法。它有时有效,有时我得到一个空白 window.
在故事板中,我让主菜单和 Window 控制器。我删除了 "contains" 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!")
}
}
大约一半的时间 window 是空的,我在控制台中看到 "Error: No main window!"。我想也许我可以使用 applicationDidBecomeActive
但这基本上是在前台调用的,这不是我需要的。
此外,它工作的时间,我登录,然后我想显示主视图控制器:
func onLoginSuccess() {
self.showViewController(NSStoryboard.mainViewController())
}
这里我也得到 "Error: No main window!"(总是)但没有任何反应。
文档说 mainWindow
为零:
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.
但为什么故事板在我启动时未完成加载或应用程序处于非活动状态?并且在登录成功时,该应用程序绝对处于活动状态并且在前台并且主要 window 始终为零。
我做错了什么?我怎样才能实施这个工作流程?或者,我可以创建一个 "parent" 视图控制器,将其连接到情节提要中的 window,然后将登录或主视图控制器作为嵌套视图控制器添加到其中。但是我真的不喜欢添加一个什么也不做的视图控制器。
我正在使用 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
与故事板中的主要 window 不同 window。
因此,我使用身份检查器创建了一个 NSWindowController
子类并将其分配给故事板中的 window。
然后我将我在应用程序委托中的逻辑移到了这个 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 为我指明了正确的方向!