Implementing NSSegmentedControl in NSToolbar to control NSTabViewController

Home / Uncategorized / Implementing NSSegmentedControl in NSToolbar to control NSTabViewController

In my macOS application, I’m trying to replicate the implementation of NSSegmentedControl in NSToolbar to control an NSTabViewController. For reference, here’s what that looks like:

So, my approach was as follows:Hide the default NSTabView header using the Interface Builder
Programmatically add an NSToolbar
Insert NSSegmentedControl as an NSToolbarItem.
Use a #selector to listen for changes to NSSegmentedControl.

Here’s the current implementation:class WindowController: NSWindowController, NSToolbarDelegate {

// MARK: – Identifiers

let mainToolbarIdentifier = NSToolbar.Identifier("MAIN_TOOLBAR")
let segmentedControlIdentifier = NSToolbarItem.Identifier("MAIN_TABBAR")

// MARK: – Properties

var tabBar: NSSegmentedControl? = NSSegmentedControl(labels: ["One", "Two"], trackingMode: NSSegmentedControl.SwitchTracking.selectOne, target: self, action: #selector(didSwitchTabs))
var toolbar: NSToolbar?
var tabBarController: NSTabViewController?

// MARK: – Life Cycle

override func windowDidLoad() {

self.toolbar = NSToolbar(identifier: mainToolbarIdentifier)
self.toolbar?.allowsUserCustomization = false
self.toolbar?.delegate = self

self.tabBar?.setSelected(true, forSegment: 0)

self.tabBarController = self.window?.contentViewController as? NSTabViewController
self.tabBarController?.selectedTabViewItemIndex = 0

self.window?.toolbar = self.toolbar

// MARK: – NSToolbarDelegate

public func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {

var toolbarItem: NSToolbarItem

switch itemIdentifier {
case segmentedControlIdentifier:toolbarItem = NSToolbarItem(itemIdentifier: segmentedControlIdentifier)
toolbarItem.view = self.tabBar
case NSToolbarItem.Identifier.flexibleSpace:toolbarItem = NSToolbarItem(itemIdentifier: itemIdentifier)

return toolbarItem

public func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [segmentedControlIdentifier, NSToolbarItem.Identifier.flexibleSpace]

public func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [NSToolbarItem.Identifier.flexibleSpace, segmentedControlIdentifier, NSToolbarItem.Identifier.flexibleSpace]

// MARK: – Selectors

@objc func didSwitchTabs(sender: Any) {

let segmentedControl = sender as! NSSegmentedControl

if (segmentedControl.selectedSegment == 0) {
self.tabBarController?.selectedTabViewItemIndex = 0
} else if (segmentedControl.selectedSegment == 1) {
self.tabBarController?.selectedTabViewItemIndex = 1


And, here it is in action:

Now, I am new to macOS development and this feels like it’s a very complicated and convoluted way of solving this problem. Is there an easier way I could achieve the same thing ? Perhaps somehow in Interface Builder ? What could be done to improve here ? What have I done wrong ?

Thanks for your time.


Read more

Leave a Reply

Your email address will not be published. Required fields are marked *