Luis Palacios
Luis Palacios

Reputation: 405

HowTo show/hide a second vertical-splitted view in Cocoa?

let me introduce. I'm an enthusiast programmer (not professional) with c, c++, java experience and now starting with Objective-C and Cocoa on MacOsx.

In my first program I would like to create two vertical-splitted views, having the left one (main) always-on and the right one to show/hide as per button press (its use will be for debugging output).

I've seen exactly what I want under Xcode 4.2 where we can Hide/Show navigator/debug/utilities. I'm looking for the "utilities" behavior, that's exactly what I want. The usage of that vertical view is to output "debugging" text from my program, I'm thinking on using the NSTextView in a NSScrollView to simulate a "Console". I know I can just use a Terminal or the Debug view of Xcode, and that's what is working now. I need this just for learning how to do it and to improve my program.

I've google a lot and read similar request but I couldn't find exactly how to do this one.

Thanks in advance for your help.

Luis

Upvotes: 2

Views: 1189

Answers (2)

Luis Palacios
Luis Palacios

Reputation: 405

as promised, here is what I finally did to solve my problem.

  • The objective: I want two vertical-splitted views:
    • Button to SHOW/HIDE the right view and window resize accordingly.
    • Left one (main) always-on and NON resizable in width (it can resize in height)
    • Right one show/hide, can resize in width/heigh, must have always a min width.
    • When Right is Hidden, Main Window min width/height equals the Left view

I created a NSSplitView (vertical) with 2 Custom View's with adequate autosizing restrictions in Interface Builder ('springs'/'struts'). Then I did the following:

Controller.h
:
@interface Controller : NSWindowController <NSSplitViewDelegate, NSWindowDelegate> {
:


Controller.m
:
// To control the Splitter (next 3 methods)
// =======================================
// The splitter cannot be moved. I always return "widthViewLeft" which is "fixed static sized to the left view width"
// I return NO to resize the left panel and YES to the right panel.

-(CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex {
    return (widthViewLeft);    
}
-(CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex {
    return (widthViewLeft);
}
-(BOOL)splitView:(NSSplitView *)splitView shouldAdjustSizeOfSubview:(NSView *)subview {
    return subview != splitViewLeft;
}

// To control the Main Window resize
// =======================================
// I allow to resize if the Right panel is open. 
// I restrict to a fixed size if the Right panel is closed(hidden), so I don't allow to resize. 

- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize 
{
    if ( [[leftViewController view] isHidden ] ) {
        proposedFrameSize.width = widthViewLeft + 2;
        proposedFrameSize.height = heightViewLeft + titleBarHeight + 2;
    }    
    return proposedFrameSize;
}


// To HIDE the right panel 
// =======================================
//
-(void)handleNotificationHideConsola:(NSNotification *)pNotification
{
    NSRect newFrame;
    NSSize newMinSize;
    NSSize newMaxSize;

    // Hide the right panel
    [[rightViewController view] setHidden:TRUE];

    // Values that do not change
    newMinSize.height = [theWindow minSize].height;    
    newMaxSize.height = [theWindow maxSize].height;    
    newFrame.origin.x = [theWindow frame].origin.x;
    //newFrame.origin.y = [theWindow frame].origin.y;

    // Values that change
    newMinSize.width = widthViewLeft;
    newMaxSize.width = widthViewLeft;
    newFrame.size.width = widthViewLeft + 2;
    newFrame.size.height = heightViewLeft + titleBarHeight + 2;
    newFrame.origin.y = [theWindow frame].origin.y + ([theWindow frame].size.height - newFrame.size.height) ;

    // Perform the change
    [theWindow setMinSize:newMinSize];
    [theWindow setFrame:newFrame display:YES animate:YES];

} 

// To SHOW the right panel 
// =======================================
//
-(void)handleNotificationShowConsola:(NSNotification *)pNotification
{
    if ( [[rightViewController view] isHidden] ) {
        NSRect newFrame;
        NSSize newMinSize;

        // Show the right panel
        [[rightViewController view] setHidden:FALSE];

    // Values that do not change
        newMinSize.height = [theWindow minSize].height;    
        newFrame.origin.x = [theWindow frame].origin.x;
        newFrame.origin.y = [theWindow frame].origin.y ;

        // Values that change
        newMinSize.width = widthViewLeft + widthViewRigth;             
        newFrame.size.width = widthViewLeft + widthViewRigth;         
        newFrame.size.height = newMinSize.height + titleBarHeight;  
        newFrame.origin.y = [theWindow frame].origin.y - (newFrame.size.height - [theWindow frame].size.height);

        // Perform the change
        [theWindow setMinSize:newMinSize];
        [theWindow setFrame:newFrame display:YES animate:YES];
    }  
} 

Thank you again @markhunte for the idea and hope the above sample helps someone else.

Luis

Upvotes: 1

markhunte
markhunte

Reputation: 6932

A very rough idea. Change the width of the view with setPosition:ofDividerAtIndex: setPosition:(CGFloat)position ofDividerAtIndex:(NSInteger)dividerIndex

Declare a CGFloat splitterlength.

And Put this in applicationDidFinishLaunching.

    splitterlength  = splitView.bounds.size.width;
[splitView setPosition:splitterlength ofDividerAtIndex:0];

Then use this Action

     - (IBAction)moveSplitter:(id)sender {

    NSArray *splitterViews =splitView.subviews;
   CGFloat splitterCheckLength =[[splitterViews objectAtIndex:0]bounds].size.width;
    CGFloat openSplitter=splitterlength/2;

    if (splitterCheckLength ==openSplitter) {
      [splitView setPosition:splitterlength ofDividerAtIndex:0];
    }else {
        [splitView setPosition:openSplitter ofDividerAtIndex:0];
    }




}

Use what ever length you want.

Saying this though. I would use normal customViews and adjust them. That way I do not have to worry about the dragging of the splitter by the user.

Upvotes: 0

Related Questions