Programmatically select NSTabViewItem broken?

I know this can't be the case, but this is driving me crazy.


I am using latest version of Swift and Storyboards. To illustrate the point I created a basic project with a NSTabViewController and two view controllers. The tab of the first view controller is selected in the Storyboard. Without subclassing the little program works fine, showing the first tab and allowing you to switch back and forth.


I have created a subclass of NSTabViewController and it looks like this:


class TabViewControl: NSTabViewController {
    @IBOutlet weak var theFirstTab: NSTabViewItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        let theTabView = theFirstTab.tabView
        theTabView?.selectTabViewItemAtIndex(1)
    }
}


All I want to do is automatically select the second tab when the view is loaded (in my acutal program I may want to select any one of the tabs to be presented to the user depending on the context in which the tab view controller was segued to).


I have linked the first NSTabViewItem to an IBOutlet. From that I get the NSTabView and then simply select the second tab. Here is the result:


http://sedawk.com/first.png


The view from the Second Tab is shown when the program starts (even though the first tab is selected in IB), but the tabs are messed up and shows the First Tab highlighed. Clicking "First Tab" does nothing - probably because it thinks it is already selected. You must select "Second Tab" and then "First Tab" again to get everything back in order.


Note that you set the same broken results (just reversed) when you select the second tab in IB and run

theTabView?.selectFirstTabViewItem(self)


http://sedawk.com/second.png


Is this a bug?

Replies

I would say that, if you get behavior that is broken, then it's a bug and you should file it.


That said, since the tab view is controlled by a controller, you should use that controller to change the selection. So, try setting self.selectedTabViewItemIndex to change the selected tab.

Doing it in ViewDidLoad is the issue, I think. You might not be guaranteed to have full access to UI elements that haven't fully entered a state of quiescence after (or still during if threaded...?) drawing and initializing.

Wrap it in a timer or an asyncAfter call.

Also, if you do it throughout your application, consider always dispatching that call to the main thread