Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OS X Cocoa Swift: Setting up a ViewController programmatically (without Storyboard or nib files)

Tags:

macos

swift

cocoa

I am currently trying to rebuild an existing project in a purely programmatic way (without storyboard and nib files). I know that there are already some posts about that, but they didn't really helped me. This is a way to solve it:

main.swift

import Cocoa

let delegate = AppDelegate()
NS Application.shared().delegate = delegate

let ret = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)`

AppDelegate.swift

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

   let viewController = ViewController()
   let window = NSWindow(contentRect: NSMakeRect(0, 0, NSScreen.main()!.frame.size.width, NSScreen.main()!.frame.size.height), styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: NSBackingStoreType.buffered, defer: false)

   func applicationDidFinishLaunching(_ aNotification: Notification) {
       viewController.view = NSView(NSMakeRect(0, 0, window.frame.size.width, window.frame.size.height))
       viewController.view.wantsLayer = true
       window.contentView!.addSubview(viewController.view)
       window.makeKeyAndOrderFront(nil)
   }

}

ViewController.swift

import Cocoa

class ViewController: NSViewController {

    override func viewDidAppear() {
        let button = NSButton(frame: NSRect(x: 150, y: 200, width: 300, height: 30))
        button.action = #selector(ViewController.buttonPressed(_:))
        button.target = self
        view.addSubview(button)
    }

    func buttonPressed(_: Any?) {
        print("OK")
    }

}

Later, the plan is to switch with these buttons between different View Controllers and show different Views. Is this the right way at all or is there a "better" way to do this? My goal is to have one window and different ViewControllers. Thank you for your help

like image 311
manu Avatar asked Feb 07 '17 15:02

manu


People also ask

How do I delete the main Storyboard in Xcode 13?

You need to go to the "Build Settings" tab and search for the "UIKit Main Storyboard File Base Name" key. Then remove the key or set the value to empty. Or you can go to the "Info" tab and remove the key "Main storyboard file base name" ( UIMainStoryboardFile ).


1 Answers

You also need to set the target on the button. The action tells it which method to call, but without a target it has nothing to call the method on.

You may also need to change your action method to allow for the sender parameter: func buttonPressed(_: Any?) {...} and set the action to #selector(ViewController.buttonPressed(_:)).

I also just noticed that your view controller is only being held in a local variable in applicationDidFinishLaunching. It should be a property of the AppDelegate so that there is a reference to it, otherwise it will get deleted right away.

like image 65
Uncommon Avatar answered Oct 20 '22 00:10

Uncommon