swiftxcodecocoanstextfieldnsviewcontroller

Why this swift code does not show up the textfield?


The code should just view a "Hello, World!" in the window. The window appears but the text is not showing. Why is that?

I can see that the window.makeKeyAndOrderFront(nil) even orders the textfield to view in front.

Errors: No errors or warnings

import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet var window: NSWindow!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Create a new window
        window = NSWindow(contentViewController: TextFieldViewController())
        // Make the window visible
        window.makeKeyAndOrderFront(nil)
    }

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

    func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
        return true
    }
}

class TextFieldViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create a label
        let label = NSTextField(labelWithString: "Hello, World!")
        label.frame = NSRect(x: 20, y: 100, width: 200, height: 20)
        // Add the label to the view
        view.addSubview(label)
    }
}

Solution

  • You should override loadView, and add the label there

    override func loadView() {
        let view = NSView(frame: NSMakeRect(0,0,400,400))
        self.view = view
    
        let label = NSTextField(labelWithString: "Hello, World!")
        label.frame = NSRect(x: 20, y: 100, width: 200, height: 20)
        
        view.addSubview(label)
    }
    

    This is because the default implementation of loadView looks for a nib file, which presumably you don't have and don't want to use.

    The documentation for NSViewController says:

    But in macOS 10.10 and later, the loadView() method automatically looks for a nib file with the same name as the view controller.

    See also the documentation for loadView:

    For example, if you have a view controller subclass called MyViewController and a nib file with the same name, you can employ the convenient initialization pattern [[MyViewController alloc] init].