Question

I am using an NSToolbar and NSWindowController to change the views of an NSWindow. When the toolbar items are selected, the view is successfully changed for the window and the window changes it's size according to the view size. Upon the initial loading of the window, the contents of the view appear as expected. However, once a toolbar item is selected the contents of the new view are not visible and when the view is switched back to the original view, it's contents are no longer visible either. Not sure what is causing this so any help would be appreciated.

#import <Cocoa/Cocoa.h>

@interface WindowController : NSWindowController {
    IBOutlet NSView *firstView;
    IBOutlet NSView *secondView;

    int currentViewTag;
}

- (IBAction)switchView:(id)sender;

@end

and

#import "WindowController.h"

@interface WindowController ()

@end

@implementation WindowController

- (id)init {
    self = [super initWithWindowNibName:@"WindowController"];
    if (self) {
    }

    return self;
}

- (void)windowDidLoad {
    [super windowDidLoad];
}

- (NSRect)newFrameForNewContentView:(NSView*)view {

    NSWindow *window = [self window];
    NSRect newFrameRect = [window frameRectForContentRect:[view frame]];
    NSRect oldFrameRect = [window frame];
    NSSize newSize = newFrameRect.size;
    NSSize oldSize = oldFrameRect.size;

    NSRect frame = [window frame];
    frame.size = newSize;
    frame.origin.y -= (newSize.height - oldSize.height);

    return frame;
}

- (NSView *)viewForTag:(int)tag {

    NSView *view = nil;
    switch (tag) {
        case 0:
            view = firstView;
            break;
        case 1:
            view = secondView;
            break;
    }

    return  view;
}

- (BOOL)validateToolbarItem:(NSToolbarItem *)item {
    if ([item tag] == currentViewTag) return NO;
    else return YES;
}

- (void)awakeFromNib {

    [[self window] setContentSize:[firstView frame].size];
    [[[self window] contentView] addSubview:firstView];
    [[[self window] contentView] setWantsLayer:YES];
}

- (IBAction)switchView:(id)sender {

    double tag = [sender tag];
    NSView *view = [self viewForTag:tag];
    NSView *previousView = [self viewForTag:currentViewTag];
    currentViewTag = tag;

    NSRect newFrame = [self newFrameForNewContentView:view];


    [NSAnimationContext beginGrouping];

    if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask)
        [[NSAnimationContext currentContext] setDuration:1.0];

    [[[[self window] contentView] animator] replaceSubview:previousView with:view];
    [[[self window] animator] setFrame:newFrame display:YES];

    [NSAnimationContext endGrouping];
}

@end
Was it helpful?

Solution

I tried out your code, and what I saw was not that the views disappeared, but that they were positioned wrongly and moved out of view. I fixed this by turning off auto layout in IB, and deselecting all the struts and springs in the size inspector. I also deselected the window's "restorable" property so that if you closed the program with view 2 visible, and reopened, the window (with view 1 inside) would be the correct size for view 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top