Nsapplicationdelegate Not Working Without Storyboard

NSApplicationDelegate not working without Storyboard

You need to do a few things here

  1. Delete NSMainStoryboardFile key/value from the plist
  2. Create a NSApplication subclass and assign it to the Principal Class (NSPrincipalClass) key.

assign custom class to principal class

The name must be fully qualified with your module name.


  1. Manually instantiate your delegate in your NSApplication subclass and assign it to the delegate property.

Make sure you keep a strong reference to your delegate object. Ive just used a let here.

class GrookApplication: NSApplication {

let strongDelegate = AppDelegate()

override init() {
super.init()
self.delegate = strongDelegate
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

e.g a simple delegate.

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

override init() {
super.init()
print("wassup")
//conceptual proof of life init override
//wait until applicationDidFinishLaunching , specially for UI
}

var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
print("yo! I'm alive")
window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 200, height: 200), styleMask: .titled, backing: .buffered, defer: false)
window.makeKeyAndOrderFront(nil)
}

}

EDIT 2018 Verified High Sierra

Do NOT try and do window or view controller initialisation inside init this leads to double app initialisation issues and crashing. The app has not finished launching at this stage. Wait until applicationDidFinishLaunching to fire any significant operations.

macOS statusBarApp without Storyboard create and close settingsWindow causing EXC_BAD_ACCESS

NSWindow is released when it is closed. Before ARC this was a usefull feature. It can be switched off by setting the isReleasedWhenClosed property to false. But then the window stays in memory when it is closed because the settingsWindow property is holding on to it. Implement delegate method windowWillClose and set settingsWindow to nil so window is released.

class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {

var settingsWindow: NSWindow!

// other methods

@objc func createWindow() {
settingsWindow = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 750, height: 500),
styleMask: [.miniaturizable, .closable, .resizable, .titled],
backing: .buffered, defer: false)
settingsWindow.isReleasedWhenClosed = false
settingsWindow.delegate = self
settingsWindow.center()
settingsWindow.title = "No Storyboard Window"
settingsWindow?.contentViewController = ViewController()
settingsWindow.makeKeyAndOrderFront(nil)
}

func windowWillClose(_ notification: Notification) {
settingsWindow = nil
}

}

OSX application without storyboard or xib files using Swift

if you don't want to have the @NSApplicationMain attribute, do:

  1. have a file main.swift

  2. add following top-level code:

     import Cocoa

    let delegate = AppDelegate() //alloc main app's delegate class
    NSApplication.shared.delegate = delegate //set as app's delegate
    NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) //start of run loop

    // Old versions:
    // NSApplicationMain(C_ARGC, C_ARGV)
    // NSApplicationMain(Process.argc, Process.unsafeArgv);

the rest should be inside your app delegate. e.g.:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {
var newWindow: NSWindow?
var controller: ViewController?

func applicationDidFinishLaunching(aNotification: NSNotification) {
newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: .resizable, backing: .buffered, defer: false)

controller = ViewController()
let content = newWindow!.contentView! as NSView
let view = controller!.view
content.addSubview(view)

newWindow!.makeKeyAndOrderFront(nil)
}
}

then you have a viewController

import Cocoa

class ViewController : NSViewController {
override func loadView() {
let view = NSView(frame: NSMakeRect(0,0,100,100))
view.wantsLayer = true
view.layer?.borderWidth = 2
view.layer?.borderColor = NSColor.red.cgColor
self.view = view
}
}

how to prevent storyboard from opening a window

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var defaultWindow:NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
defaultWindow = NSApplication.sharedApplication().windows.first as? NSWindow
defaultWindow.close()

}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
@IBAction func menuClick(sender: AnyObject) {
defaultWindow.makeKeyAndOrderFront(nil)
}
}

update: Xcode 7.1.1 • Swift 2.1

NSApplication.sharedApplication().windows.first?.close()

Crash when closing window in a MacOS application?

The problem is the window is automatically released (and thus deallocated) upon closure. This, combined with the automatic reference counting, presumably creates a sort of double free error. To solve this problem without disabling ARC or disabling releaseWhenClosed, Window is made a global or instance variable. Doing so will prevent ARC from releasing the window after already having been released by being closed.

NSWindow *Window;
// ...
- (void)applicationDidFinishLaunching:(NSNotification *)Notification {
Window = [[NSWindow alloc] initWithContentRect:(NSRect){.size = {800, 512}} styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:YES];
[Window center];
[Window makeKeyAndOrderFront:Window];
// Insert code here to initialize your application
}

applicationDidFinishLaunching not called, using storyboards and swift3

Even if your app is running as an agent your storyboard is supposed to have this structure:

Sample Image

If not, drag a blue cube (object) into the application scene, set the class of the object to AppDelegate and control-drag from Application to App Delegate and select delegate.

If you even have no Application Scene, create a new project with storyboard enabled, delete your current Main.storyboard file and drag the Main.storyboard of the new created project into your current project.

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

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))
}


Related Topics



Leave a reply



Submit