Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTabViewController ignoring transitions and title propagation settings

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
like image 978
Drew McCormack Avatar asked Dec 15 '14 16:12

Drew McCormack


2 Answers

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.

like image 136
Pierre Bernard Avatar answered Oct 07 '22 01:10

Pierre Bernard


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
like image 25
vomi Avatar answered Oct 07 '22 00:10

vomi