Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a subclass of NSViewController without a xib file

Tags:

I am currently writing an OS X application using Swift 2. I am wanting to build the UI without XIBs or Storyboards. The problem I am having is on initializing a custom ViewController that I can put my views in.

Here is my AppDelegate:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

  @IBOutlet weak var window: NSWindow!
  var viewController: MyViewController?

  func applicationDidFinishLaunching(aNotification: NSNotification) {
    viewController = MyViewController()
    self.window.contentView!.addSubview(viewController!.view)
  }

  func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
  }

}

And MyViewController:

class MyViewController: NSViewController {
  var textField: NSTextField?

    override func viewDidLoad() {
      super.viewDidLoad()

      textField = NSTextField(frame: NSRect(x: 10, y: 10, width: 100, height: 100))
      textField!.bezeled = false
      textField!.drawsBackground = false
      textField!.editable = false
      textField!.selectable = false
      textField!.stringValue = "TEST"
      self.view.addSubview(textField!)
    }

}

The problem is that when I add the viewController's view as a subview of the window's contentView, I get the following error and the view doesn't load.

2015-12-06 17:34:18.204 Test[9682:1871784] -[NSNib 
_initWithNibNamed:bundle:options:] could not load the nibName: 
Test.MyViewController in bundle (null).

I'm not sure what I'm doing wrong - any help would be appreciated.

like image 870
Rohan Avatar asked Dec 06 '15 23:12

Rohan


1 Answers

From the NSViewController documentation:

If you pass in a nil for nibNameOrNil then nibName will return nil and loadView will throw an exception; in this case you must invoke setView: before view is invoked, or override loadView.

The initializer for MyViewController() uses nil for the nibName.

Two potential fixes:

1. Set the view in your AppDelegate

func applicationDidFinishLaunching(aNotification: NSNotification) {
    viewController = MyViewController()
    viewController!.view = NSView() // added this line; edit to set any view of your choice
    self.window.contentView!.addSubview(viewController!.view)
}

Alternately,

2. Override loadView in your subclassed ViewController

import Cocoa

class MyViewController: NSViewController {
    var textField: NSTextField?

    override func loadView() {
        self.view = NSView() // any view of your choice
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        textField = NSTextField(frame: NSRect(x: 10, y: 10, width: 100, height: 100))
        textField!.bezeled = false
        textField!.drawsBackground = false
        textField!.editable = false
        textField!.selectable = false
        textField!.stringValue = "TEST"
        self.view.addSubview(textField!)
    }

}
like image 191
nishanthshanmugham Avatar answered Sep 20 '22 13:09

nishanthshanmugham