0

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 a Tab View Controller (Style = toolbar)
  • I have a Tabless Tab View
  • I have 3 Tab Items. For testing I have only subclassed one of them to the subclass below

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

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
Marco
  • 81
  • 1
  • 8
  • Have you set the class of that one tab view item to `MyTabViewItem` in IB? – vadian Jun 24 '18 at 17:09
  • Yes. The class is recognised in IB and I have set it to that class. – Marco Jun 24 '18 at 17:16
  • My next step would be to override the `-initWithIdentifier` constructor, set a breakpoint, and see if your custom object is even getting created. If not, that's your problem (look to IB). If yes, then check to see if `identifier`, `view`, and `tabView` properties are getting set, indicating that this tab view item has gotten installed into the tab view. Alternatively, simply break the app and use the Debug Visual Hierarchy tool to see if your view object(s) are where you expect them to be. – James Bucanek Jun 24 '18 at 19:12
  • Thank you for your comment. I am not sure I understand all of it, however the tab item is getting created and works as intended. The views are displayed as they should when I click on the different tabs. I just cannot seem to be able to modify the item's width. Below I will post another bit of code I just inserted which seems to do something, but not all that I need. – Marco Jun 24 '18 at 19:55

2 Answers2

1

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.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
0

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).

Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
Marco
  • 81
  • 1
  • 8