NSTabViewController ignoring transitions and title propagation settings

3.1k views Asked by At

I am trying to create a preferences panel for my app using storyboards and the new NSTabViewController class.

I can get it working, but the transition setting in the storyboard seems to be ignored. It just jumps from one tab to the next, with the size of the window changing instantaneously.

I thought it might depend on whether I use autolayout or not, but it didn't seem to change the transition behavior when I toggled it.

I also have the 'Propagates title' setting checked. I had expected that it would take the label of the tab item, or the title of the view controller, and propagate that as the window title, but it doesn't seem to do that.

Anyone got this to work?

Here is a simple sample app I am testing with: https://www.dropbox.com/s/roxaplxy5gtlqns/Again.zip?dl=0

Update: Got this working thanks to Pierre. Ended up making a nice transitioning preferences window by subclassing NSTabViewController as follows:

@implementation MCPreferencesTabViewController

-(void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
    [super tabView:tabView willSelectTabViewItem:tabViewItem];

    NSTabViewItem *currentTabItem = tabView.selectedTabViewItem;
    currentTabItem.view.hidden = YES;
    tabViewItem.view.hidden = YES;

    NSWindow *window = self.view.window;
    NSSize contentSize = tabViewItem.view.fittingSize;
    NSSize newWindowSize = [window frameRectForContentRect:(CGRect){CGPointZero, contentSize}].size;

    NSRect frame = [window frame];
    frame.origin.y += frame.size.height;
    frame.origin.y -= newWindowSize.height;
    frame.size = newWindowSize;

    [self.view.window setFrame:frame display:NO animate:YES];
}

- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
    [super tabView:tabView didSelectTabViewItem:tabViewItem];
    tabViewItem.view.hidden = NO;
}

@end
3

There are 3 answers

2
Pierre Bernard On BEST ANSWER

You need to make the NSTabViewController the delegate of the NSTabView.

In Interface Builder, control-drag from No Shadow Tab View to Tab View Controller and set the delegate outlet.

One would expect Interface Builder to set this up correctly when creating a new tab view controller. It does not.

0
JKaz On

Or in viewDidLoad() for the NSTabViewController, include

    self.tabView.delegate = self
0
vomi On

Please note that this was true until Xcode 9. Since Xcode 9, you need to remove (or not add it) this line:

self.tabView.delegate = self

otherwise you will receive an error:

*** Assertion failure in -[YourApp.CustomTabView setDelegate:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1561.0.100/AppKit.subproj/NSTabView.m:2766
2017-10-25 19:29:06.301282+0200 YourApp[23106:5687795] Failed to set (contentViewController) user defined inspected property on (NSWindow): 
A TabView managed by a TabViewController cannot have its delegate modified