Search code examples
swiftcocoansviewcontrollernswindowcontroller

macOS: How to create and launch a NSViewController without using Xib/Storyboard


I want to show NSViewController without using storyboard and Xib. I am already referred lot and can't get work. WindowController is not showing. Please see attached codes & Project.

main.swift

import Cocoa

print("Hello, World!")

let delegate = AppDelegate()
NSApplication.shared.delegate = delegate
 
let ret = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

AppDelegate.Swift

import Cocoa
 
class AppDelegate: NSObject, NSApplicationDelegate {
 
    func applicationDidFinishLaunching(_ aNotification: Notification) {
 
        WindowController().showWindow(self)
    }
 
 
}

WindowController.swift

import Cocoa

class WindowController: NSWindowController, NSWindowDelegate {
 
    init() {
        
        let window = Window()
 
        super.init(window: window)
        
        window.delegate = self
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Window.swift

import Cocoa

class Window: NSWindow {

    init() {
        
        let screen  = NSScreen.main!.frame
        let origin = NSPoint(x:screen.width/2, y: screen.height/2)
        
        super.init(contentRect: NSRect(origin: origin, size: NSSize(width: 600, height: 400)), styleMask: [.titled,.resizable,.miniaturizable,.closable], backing: .buffered, defer: false)
        
        self.contentViewController = ViewController()
    }
}

ViewController.swift

import Cocoa

class ViewController: NSViewController {
    
    override func loadView() {

        view = NSView()
    }
    
    init() {
          
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

         view.wantsLayer = true
         view.layer!.backgroundColor = NSColor.red.cgColor
    }
}

The code is running and viewDidLoad is calling. But window is not visible. Here is attached project. Please help me to find solution. Thanking you in advance!

Update 1.0:

I created WindowController as strong reference. Yes, It's works to keep Window controller instead of deinit. But NSViewController still not showing.

class AppDelegate: NSObject, NSApplicationDelegate {
 
    let controller = WindowController()
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
 
        controller.showWindow(self)
    }
 
}

Solution

  • The size of the view is (0, 0) and the window is resized to the fit the view. Use a bigger view:

    override func loadView() {
    
        view = NSView(frame: NSMakeRect(0, 0, 500, 500))
    }