Connect to ViewController from AppDelegate (Swift)

后端 未结 5 1167
Happy的楠姐
Happy的楠姐 2021-02-04 15:55

I have created a new OS X Cocoa Application using the standard Xcode Swift template (using StoryBoards).

I have implemented an IBAction in AppDelegate.swift to handle wh

相关标签:
5条回答
  • 2021-02-04 16:12

    You can access the mainWinow property and the contentViewController property to create a reference to your custom ViewController class. This is similar to the iOS rootViewController property.

    let rootViewController = NSApplication.shared().mainWindow?.windowController?.contentViewController as! ViewController
    

    Now you can use this reference to access IBOutlets on your main storyboard from your AppDelegate.

    rootViewController.myTextView.textStorage?.mutableString.setString("Cats and dogs.")
    

    This is good for a simple app with one Window with one ViewController.

    0 讨论(0)
  • 2021-02-04 16:12

    If you control-drag from the menu to the first responder (red cube above menu) and picked an existing action, then you can "responder chain" to your view controller. In my case I attached Open to openFile and then in my view controller I added the following

    override var acceptsFirstResponder: Bool {
        return true
    }
    
    func openFile(sender: NSMenuItem) {
        print("In view controller")
    }
    

    and it worked without any changes in AppDelegate. Most of the menus are already hooked up to first responder so just add the matching function name in your view controller.

    See this comment and this document on Event Handling Basics for more info.

    0 讨论(0)
  • 2021-02-04 16:13

    I was stuck trying to do this same thing recently and managed to get the event I needed to update my view by creating the @IBAction in my ViewController and control dragging to my Application's First Responder (above the menu in my storyboard view).

    Here's the question that got me out of the woods: Application Menu Items Xcode

    And thanks to Bluedome for the suggestion to connect it to First Responder's action.

    0 讨论(0)
  • 2021-02-04 16:23

    In Swift 5 and accessing new windows array:

    @IBAction func menuAction(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateInitialViewController()
        // The windows in the array are ordered from back to front by window level;
        // thus, the last window in the array is on top of all other app windows.
        // On app launch, UIApplication.shared.windows.count == 1 anyway.
        if let window = UIApplication.shared.windows.last {
            window.rootViewController = controller
        }
    }
    
    0 讨论(0)
  • 2021-02-04 16:24

    It seems that AppDelegate can connect to objects only within Application Scene in a storyboard. If you want to get a ViewController, instantiate it from a storyboard.

    sample:

    @IBAction func menuAction(sender: AnyObject) {
        if let storyboard = NSStoryboard(name: "Main", bundle: nil) {
            let controller = storyboard.instantiateControllerWithIdentifier("VC1") as NSViewController
    
            if let window = NSApplication.sharedApplication().mainWindow {
                window.contentViewController = controller // just swap
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题