Marco
Marco

Reputation: 89

Cannot modify NSTabViewItem

I may be getting lost in a glass of water as I am not an experienced developer but I cannot seem to be able to implement a simple override to modify the size of an NSTabView item.

I have created a new subclass of NSTabViewItem: MyTabViewItem and subclassed one of the 3 tab Items. The code is:

import Cocoa

class MyTabViewItem: NSTabViewItem {

    override func drawLabel(_ shouldTruncateLabel: Bool, in labelRect: NSRect) {

        var size = self.sizeOfLabel(false)
        size.width = 180 
        print("Draw!!")         
    }


    override func sizeOfLabel(_ computeMin: Bool) -> NSSize {

        var size = super.sizeOfLabel(false)      
        size.width = 180      
        print("Draw!!")
        return size      
    }       
}

Everything works, except the subclassing. The Tabs appear, they do operate by switching the views and the program runs as it should. Except that it does not resize the Tab Item. The code in the subclass MyTabViewItem is never reached (it never prints Draw!! as it should.

I cannot understand what I am missing here. I have not read of any IB connection to make (and I cannot seem to be able to connect the Tab Items anyways). Please apologise if it isa trivial question but I have searched everywhere and not found anything to help me.

Thank you

Upvotes: 0

Views: 816

Answers (2)

Marco
Marco

Reputation: 89

I have also subclassed the NSTabViewController as follows:

import Cocoa

class MyTabViewController: NSTabViewController {

    @IBOutlet weak var TradingTabItem: MyTabViewItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        print("Loaded Tab View")
        TradingTabItem.label = "New"

        // Do view setup here.

    }

}

What happens now is that the tab item in my subclass (the only one of the 3 I subclassed) does change its label string to New. However, even if I have added the item as an IBOutlet here, it still does not change seize (and the overridden sizeOfLabel function is not reached).

Upvotes: 0

rob mayoff
rob mayoff

Reputation: 385590

You said:

  • I have a Tabless Tab View

This is your problem. An NSTabView only asks an NSTabViewItem to drawLabel if the NSTabView itself is responsible for drawing the tab bar, but you have a “Tabless” tab view. (“Tabless” is the default style when you drag an NSTabViewController into a storyboard.)

You also said:

  • I have a Tab View Controller (Style = toolbar)

So you don't even want the tab view to draw a tab bar; you want items in the window toolbar to select tabs (like in Xcode's preference window).

Your ability to customize the toolbar items created for your tabs is limited. You can subclass NSTabViewController and override toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:, like this:

override func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
    let toolbarItem = super.toolbar(toolbar, itemForItemIdentifier: itemIdentifier, willBeInsertedIntoToolbar: flag)
    if
        let toolbarItem = toolbarItem,
        let tabViewItem = tabViewItems.first(where: { ($0.identifier as? String) == itemIdentifier.rawValue })
    {
        toolbarItem.label = "\(tabViewItem.label) 😀"
    }
    return toolbarItem
}

But I found that making other changes didn't work well:

  • Setting toolbarItem.image didn't work well for me.
  • Setting toolbarItem.view made the item stop receiving clicks.

Note that the minSize and maxSize properties are only used if toolbarItem.view is set.

Your best bet is probably to manage the toolbar yourself, without trying to use NSTabViewController's support.

Upvotes: 1

Related Questions