manu manu - 1 year ago 143
Swift Question

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

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 what I've got so far:


import Cocoa

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

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


import Cocoa

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)

class AppDelegate: NSObject, NSApplicationDelegate {

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



import Cocoa

class ViewController: NSViewController {

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

func buttonPressed(_: Any?) {


But when I press the button, it gets not executed.

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

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download