Home > front end >  Programmatically created NSToolbar does not call itemForItemIdentifier method
Programmatically created NSToolbar does not call itemForItemIdentifier method

Time:10-06

I'm trying to programmatically create an NSToolbar on a window but it does not seem to be calling the itemForItemIdentifier method (I used a breakpoint and it does not do anything), If I remove that method Xcode complains that it "does not implement all required methods", but when I add it back it does not say anything. And it renders the items even when I return nil from that method

I'm on macOS Monterey and Xcode 13.3

Code:

import Cocoa

class MainWindowController: NSWindowController {

    override func windowDidLoad() {
        super.windowDidLoad()
                
        let toolbar = NSToolbar()
        toolbar.delegate = self
        toolbar.displayMode = .default

        self.window?.toolbar = toolbar
    }
    
}

extension MainWindowController: NSToolbarDelegate {
    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [
            .toggleSidebar,
            .print
        ]
    }
    
    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        return NSToolbarItem(itemIdentifier: itemIdentifier)
    }
    
    func toolbarWillAddItem(_ notification: Notification) {
        print("toolbarWillAddItem")
    }
    
    func toolbarDidRemoveItem(_ notification: Notification) {
        print("toolbarDidRemoveItem")
    }

    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [
            .toggleSidebar,
            .print
        ]
    }

    func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return []
    }
}

Screenshot:

screenshot of the issue

CodePudding user response:

The itemForItemIdentifier:willBeInsertedIntoToolbar: method is only called for non-stock toolbar items. Right now you only have 2 toolbar items, the toggle sidebar one and the print one. NSToolbar doesn't need to call itemForItemIdentifier:willBeInsertedIntoToolbar: for those items, because it handles creating them itself. My Swift is a bit rusty, but adding something like the following should cause that delegate method to be called:

func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> 
                                [NSToolbarItem.Identifier] {
    return [
        .toggleSidebar,
        .print,
        NSToolbarItem.Identifier("myOwn"),
    ]
}

func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> 
                               [NSToolbarItem.Identifier] {
    return [
        .toggleSidebar,
        .print,
        NSToolbarItem.Identifier("myOwn"),
    ]
}

That method should then be called passing in the NSToolbarItem.Identifier("myOwn") to give you a chance to create the toolbar item corresponding to that identifier.

  • Related