Search code examples
macosswiftxcode6nstextfield

Creating NSTextFields programmatically in Swift


Is there any way to create NSTextFields completely programmatically using Swift? I am creating a mac application that I would rather not connect to a storyboard, but I can't figure out any method of creating NSTextFields besides making an IBOutlet. By the way, I'm new to programming, so sorry for my lack of technical language.

Thank You!

Edit:

Here's the code that I have tried so far:

When I do this, I get the error message "fatal error: unexpectedly found nil while unwrapping an Optional value." The same error message pops up whether I make test an SKView or an NSView. If I try defining the IBOutlet as "view" instead of "test", it tells me that I can't override the stored property "view".

import Foundation
import Cocoa
import SpriteKit

class SettingsScene: SKScene {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var test: SKView!

    var ballSpeedText = NSTextField(frame: NSMakeRect(20,20,200,40))

    override func didMoveToView(view: SKView) {
        ballSpeedText.textColor = NSColor.redColor()
        ballSpeedText.stringValue = "Test"
        test.addSubview(ballSpeedText)
    }

If I try doing it without creating any IBOutlets, just using view, I don't get any errors, but the text field does not show up:

import Foundation
import Cocoa
import SpriteKit

class SettingsScene: SKScene {

    var ballSpeedText = NSTextField(frame: NSMakeRect(20,20,200,40))

    override func didMoveToView(view: SKView) {
        ballSpeedText.textColor = NSColor.redColor()
        ballSpeedText.stringValue = "Test"
        view.addSubview(ballSpeedText)
    }

Solution

  • You can do it easily. Just connect your view to an outlet, then you can do like this:

    import Cocoa
    
    class AppDelegate: NSObject, NSApplicationDelegate {
    
        private var window: NSWindow?
    
        let textField = NSTextField(frame: .init(x: 20, y: 20, width: 200, height: 40))
    
        func applicationDidFinishLaunching(_ aNotification: Notification) {
            window = NSWindow(contentRect: NSScreen.main?.frame ?? .zero,
            styleMask: [.miniaturizable, .closable, .resizable, .titled],
            backing: .buffered,
            defer: false)
            window?.title = "My App"
            window?.makeKeyAndOrderFront(nil)
            
            textField.textColor = .red
            textField.stringValue = "Hello World !!!"
            window?.contentView?.addSubview(textField)
        }
    
        func applicationWillTerminate(_ aNotification: Notification) {
            // Insert code here to tear down your application
        }
    }
    

    Add a main.swift file to your project:

    import Cocoa
    
    let delegate = AppDelegate()
    NSApplication.shared.delegate = delegate
    _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
    

    And in your target deployment info, remove the main.storyboard from the Main Interface:

    enter image description here