Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Introduction:

I want to create an app that displays some "user guide" on its first launch, I've already finished the part that detects if the app is first launch, but when it comes to the setting view controller part, I can't figure out how to do it.

Current Situation:

I've done a lot of researches and seen a lot of Q/A articles on topics like "How to set initial view controller programmatically in swift", but basically all of them are using ios development as an example, which none of their UIWindow or UINavigationController(rootViewController:) matches in the OSX development. And then I found out it seems that there is no such thing as didFinishLaunchingWithOptions in the AppDelegate.swift file, instead, there's only an applicationDidFinishLaunching(_ aNotification: Notification).

Question:

I already unchecked the Is Initial Controller option for both of my View Controllers, and both of them has Storyboard ID (identifier?) and their own specified class.

MainPageController

UserGuidePageController

Or should I specify and identify my Window Controllers too? Cuz' I have no idea about what to do with the Window Controllers..

What do I need to do in order to set the initial view controller for my application in AppDelegate?

P.S. Here is the picture of my interface view:

Storyboard interface

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
  }
}

I tried this way, but it didn't work out pretty well, is there anything wrong with my code?

like image 677
AgentBilly Avatar asked Oct 03 '18 11:10

AgentBilly


People also ask

How do I change the initial view controller in storyboard?

Specifying the Initial View Controllerstoryboard and select the Tab Bar Controller Scene. On the right, select the Attribute inspector. You'll find a checkbox named Is Initial View Controller. Checking this box will identify the selected view controller as the initial entry point for the storyboard you're on.


1 Answers

at the beginning you need to handle such scenario from the app delegate class for iOS APPs

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
}

// this code I just write it on sublime not from xcode so may be you need to format it and fix any syntax problems

For OSX MainWindow: 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)
    }
like image 156
Abuzeid Avatar answered Oct 21 '22 00:10

Abuzeid