Adding Items to The Dock Menu from My View Controller in My Cocoa App

Adding Items to the Dock Menu from my View Controller in my Cocoa App

Since applicationDockMenu: is a delegate method, having an instance method add menu items would conflict with the delegate return.

What you could do is make the dock menu a property/instance variable in your application delegate class. This way, your view controller could modify the menu either by passing the reference to the menu from your application delegate to your view controller (which you would have a dockMenu property) or referencing it globally (less recommended).

class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
var dockMenu = NSMenu(title: "MyMenu")

func applicationDidFinishLaunching(aNotification: NSNotification) {
if let viewController = ViewController(nibName: "ViewController", bundle: nil) {
viewController.dockMenu = self.dockMenu
self.window.contentViewController = viewController
}
}

func applicationDockMenu(sender: NSApplication) -> NSMenu? {
return self.dockMenu
}

class ViewController: NSViewController {
var dockMenu: NSMenu?

// Button action
@IBAction func updateDockMenu(sender: AnyObject) {
self.dockMenu?.addItem(NSMenuItem(title: "An Item", action: nil, keyEquivalent: ""))
}
}

Re-create Cocoa application menubar

The behavior you're describing is normal for background applications. If you don't have an icon in the Dock, you don't get your own menubar, even if you have a window in the foreground.

How does NSDocumentController slot into my document based app?

I believe you’re misunderstanding the goal of NSDocumentController, probably because its name is similar to NSWindowController and NSViewController.

In Cocoa MVC, a controller mediates a view and a model. When dealing with windows, it’s common for the controller to be a subclass of NSWindowController and, in the case of views, a subclass of NSViewController.

In the document-based architecture, an NSDocument class is a mediator between the model that represents the document and the corresponding views and controllers. Essentially, it is responsible for recreating the model based on an external representation and providing some way of attaching controller behaviour corresponding to the model and the view. Two designs are commonly used for that:

  • The NSDocument subclass effectively acts as a window (potentially view as well) controller — for example, by implementing IBActions. This should work for simple applications but it can quickly lead to a bloated NSDocument subclass that deals with more than it should. The documentation says:

    The default Document-based Application project template does not subclass NSWindowController. You do not need to subclass NSWindowController if you are writing a simple application. However, if you are writing an application with more advanced requirements, you will almost certainly want to do so.

  • The NSDocument subclass creates custom window controllers, which in turn implement controller behaviour, potentially using view controllers as well.

In many (most?) cases there is no need for an NSDocumentController subclass — the controller part of your application would be inside window controllers, view controllers, or your NSDocument subclass. That said, there are some situations where it might be necessary as explained in the documentation:

Usually, you should not need to subclass NSDocumentController. Almost anything that can be done by subclassing can be done just as easily by the application’s delegate. However, it is possible to subclass NSDocumentController if you need to.

For example, if you need to customize the Open panel, an NSDocumentController subclass is clearly needed. You can override the NSDocumentController method runModalOpenPanel:forTypes: to customize the panel or add an accessory view. The addDocument: and removeDocument: methods are provided for subclassers that want to know when documents are opened or closed.

How do you hide the menu bar in a Cocoa app?

There are two good ways I know of to do this.

1
In Cocoa, you can call the NSMenu class method setMenuBarVisible: to show or hide the menu bar.

As of this writing, the documentation for the NSMenu class does not tell you the following additional information.

The menu bar will only be hidden for the app that calls this method.
The Dock will also be hidden at the same time.

(This is true at least in 10.9 and I have not tested any other versions.)

This is useful when you want to use an app in a full screen way where you have a cover window, a borderless window the size of the screen.
The nice feature of this (as opposed to playing with LSUIElement settings) is that your app can continue to be in the application switcher cycling, as well as visible in the Dock when other apps are active.
This allows users to still activate a full screen app through the Dock or application switcher.
That means you can still use your app's Dock menu to access a preferences window for your app or other features.
This is incredibly convenient if your app is indeed a full screen cover window that runs at a window level higher than other apps, but you still want to make preferences and the ability to quit your app available, and you want your app's visual functionality available when other apps are active.

2
Another option is via NSApplication's method setPresentationOptions: with the arguments from NSApplicationPresentationOptions enum, such as option NSApplicationPresentationHideMenuBar
With this approach be very wary of reading the documentation, although it gives you additional options, and is still app-specific only, you need to know that some of the options are mutually exclusive. There are rules you must follow, or you get nothing but exceptions spewed to the console.

3 There is a 3rd and crappy option. If you have a helper app that is a daemon, you can use it to change your app's LSUIElement state and basically relaunch your app. It's dumb and it takes you out of the app switcher completely, which is great if you really are writing something that should not be there, but that is rare.

Customize how to open an item from the Open Recent NSMenu

your NSApplicationDelegate class needs to respond to opening of files and in order to make mac os x recognize your application being able to open such applications you need to modify your info.plist



Related Topics



Leave a reply



Submit