如何使用 Swift 4 Xcode 10 从 Cocoa 中的故事板以编程方式设置初始控制器?

How to set initial controller programmatically from storyboard in Cocoa using Swift 4 Xcode 10?

简介:

我想创建一个在首次启动时显示一些 "user guide" 的应用程序,我已经完成了检测应用程序是否首次启动的部分,但是当涉及到设置视图控制器部分时,我不知道该怎么做。

现状:

我做了很多研究,也看过很多Q/A文章,主题都是"How to set initial view controller programmatically in swift",但基本上都是以ios开发为例,他们的 UIWindowUINavigationController(rootViewController:) 中的 none 匹配 OSX 开发。然后我发现 AppDelegate.swift 文件中似乎没有 didFinishLaunchingWithOptions 这样的东西,而是只有 applicationDidFinishLaunching(_ aNotification: Notification).

问题:

我已经取消选中我的两个视图控制器的 Is Initial Controller 选项,并且它们都有 Storyboard ID(标识符?)和它们自己指定的 class.

MainPageController

UserGuidePageController

或者我是否也应该指定和识别我的 Window 控制器?因为我不知道如何处理 Window 控制器..

我需要做什么才能在 AppDelegate 中为我的应用程序设置初始视图控制器?

P.S。这是我的界面视图的图片:

故事板界面

AppDelegate.swift

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

  let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: Bundle.main)
  var window = MainWindow().window

  func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) - > Bool {
    return true
  }

  func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
    let firstLaunch = UserDefaults.isFirstLaunch()
    let mainPageController = storyboard.instantiateController(withIdentifier: NSStoryboard.Name("MainPageController")) as? MainPageController
    let userGuidePageController = storyboard.instantiateController(withIdentifier: NSStoryboard.Name("MainPageController")) as? UserGuidePageController
    if !firstLaunch {
      print("first run")
      window?.contentViewController = userGuidePageController
    } else {
      print("not first run")
      window?.contentViewController = mainPageController
    }
  }

  func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
  }
}

我试过这种方法,但效果不是很好,我的代码有什么问题吗?

一开始你需要处理来自应用程序委托的这种情况class iOS 个应用

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


let shouldShowUserGuide = // your cached key from user defaults for example

let mainController = //MainPageController Instance
let userGuide = //UserGuidePageController Instance


if shouldShowUserGuide {
window.rootViewController = userGuide 
}else{
window.rootViewController = mainController
}
window.makeKeyAndVisisble()
  return true
}

// 这段代码是我在 sublime 上写的,不是来自 xcode 所以你可能需要格式化它并修复任何语法问题

对于OSX 主窗口:NSWindowController

func applicationDidFinishLaunching(_ aNotification: Notification) {
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: Bundle.main)
        var window = storyboard.instantiateController(withIdentifier: "MainWindow") as! NSWindowController
        let firstLaunch = true//UserDefaults.isFirstLaunch()
        let mainPageController = storyboard.instantiateController(withIdentifier: "MainController") as! NSViewController
        let userGuidePageController = storyboard.instantiateController(withIdentifier: "UserGuideController") as! NSViewController
        if firstLaunch {
            print("first run")
            window.contentViewController = userGuidePageController
        } else {
            print("not first run")
            window.contentViewController = mainPageController
        }
        window.showWindow(self) // needed as long as your window controller has no static window content (No Content View Controller)
    }

MacOS 和 iOS 初始化函数调用的顺序不同。 applicationDidFinishLaunching 在初始 Window Controller viewDidLoad 方法被调用之后才会被调用。但没关系。您可以在 Window Controller viewDidLoad 方法中执行您的逻辑。

  1. 将一个 Window 控制器拖放到情节提要上,并为其指定一个情节提要 ID。此外,设置自定义 Class 名称。例如,“EntryWindowWC”。但不要将它连接到内容视图控制器。您将以编程方式执行此操作。

  2. 创建一个NSWindow控制器swiftclass

import Cocoa

class EntryWindowWC: NSWindowController
{
    override func windowDidLoad()
    {
        super.windowDidLoad()
    
        let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: Bundle.main)
        
        if (Security.shared.isLifetimeMember())
        {
            let homepage = storyboard.instantiateController(withIdentifier: "homepageStoryId") as! NSViewController
            window!.contentViewController = homepage
        }
        else
        {
            let subscription = storyboard.instantiateController(withIdentifier: "subscriptionStoryId") as! NSViewController
            window!.contentViewController = subscription
        }
    }
}
  1. 构建,运行,完成。