I want to be able to add a button to the title bar of all windows that open on a Mac.
The button will go on the right hand side, opposite the X -
This is really a two-part question. As for how to get a button up there, I’d suggest using -[NSWindow standardWindowButton:]
to get an existing window button and its superview (i. e. the title bar):
NSButton *closeButton = [window standardWindowButton:NSWindowCloseButton]; // Get the existing close button of the window. Check documentation for the other window buttons.
NSView *titleBarView = closeButton.superview; // Get the view that encloses that standard window buttons.
NSButton *myButton = …; // Create custom button to be added to the title bar.
myButton.frame = …; // Set the appropriate frame for your button. Use titleBarView.bounds to determine the bounding rect of the view that encloses the standard window buttons.
[titleBarView addSubview:myButton]; // Add the custom button to the title bar.
The plugging-in is probably easiest to do as a SIMBL plug-in.
This answer addresses the latest Xcode Version 9.3
Swift 4 - In NSWindowController
add the below code
if let window = window {
let myButton = NSButton()
myButton.title = "Help"
myButton.bezelStyle = .rounded
let titleBarView = window.standardWindowButton(.closeButton)!.superview!
titleBarView.addSubview(myButton)
myButton.translatesAutoresizingMaskIntoConstraints = false
titleBarView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[myButton]-2-|", options: [], metrics: nil, views: ["myButton": myButton]))
titleBarView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-1-[myButton]-3-|", options: [], metrics: nil, views: ["myButton": myButton]))
}
Hope this is helpful.
The officially-supported way to add a title bar button in OS X 10.10 (Yosemite) and later is by creating an NSTitlebarAccessoryViewController and adding it to your window using -[NSWindow addTitlebarAccessoryViewController].
For example, I have a window that has a title bar accessory view:
To set this up, I started by adding a standalone view to the window controller scene in my storyboard. (You don't have to use a storyboard but I did in this project.)
My accessory view is an NSView
with an NSButton
subview. The button title uses Font Awesome to display the pushpin.
I connected the accessory view to an outlet (cleverly named accessoryView
) in my NSWindowController
subclass:
Then, in my window controller's windowDidLoad
, I create the NSTitlebarAccessoryViewController
, set its properties, and add it to the window:
@IBOutlet var accessoryView: NSView!
var accessoryViewController: NSTitlebarAccessoryViewController?
override func windowDidLoad() {
super.windowDidLoad()
createAccessoryViewControllerIfNeeded()
}
fileprivate func createAccessoryViewControllerIfNeeded() {
guard self.accessoryViewController == nil else { return }
let accessoryViewController = NSTitlebarAccessoryViewController()
self.accessoryViewController = accessoryViewController
accessoryViewController.view = accessoryView
accessoryViewController.layoutAttribute = .right
self.window?.addTitlebarAccessoryViewController(accessoryViewController)
}