Jonathan Patt
Jonathan Patt

Reputation: 1572

Subview of custom NSView is resizing itself to fit within its superview

I have a custom NSView which contains a subview—for the purposes of solving this issue, the top level view is simply acting as a container and automatically resizes to fit within the window. Its subview draws a rectangle 10 pixels inset from the edge of the window, except for the bottom, which should get clipped by the window until it's resized to show the entire rectangle. It does not, however, behave as I intend, and instead shrinks the height of the rectangle when its superview has a smaller height than it does. How do I avoid this and have it stay at its proper height and instead get clipped when the superview is smaller?

The parent view's implementation code is:

- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    if (self) {
        subView = [[SubView alloc] initWithFrame:frameRect];
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor grayColor] set];
    [subView setFrame:NSMakeRect(10, 10, dirtyRect.size.width - 20, 500)];
    [self addSubview:subView];
}

- (BOOL)isFlipped {
    return YES;
}

And the subview is just:

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor blackColor] set];
    [NSBezierPath strokeRect:dirtyRect];
}

- (BOOL)isFlipped {
    return YES;
}

Upvotes: 1

Views: 5021

Answers (2)

James Eichele
James Eichele

Reputation: 119184

As ericgorr pointed out, the autoResizingMask should take care of the resizing issue.

However, I notice that you are adding your subview in drawRect, which is not the right place to do it. drawRect is called many times during the lifetime of your program, but addSubview: only needs to be (and only should be) called once, like so:

- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    if (self) {
        subView = [[SubView alloc] initWithFrame:frameRect];
        [self addSubview:subView]; // this view now owns subView ...
        [subView release];         // ... so we can release our copy
    }
    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect { 
    [[NSColor grayColor] set]; 
    [subView setFrame:NSMakeRect(10, 10, [self bounds].size.width - 20, 500)];
} 

Note also the use of [self bounds] instead of dirtyRect. dirtyRect is a rectangle describing the region which needs to be redrawn. This will not always be the entire bounding rectangle of your view. [self bounds], on the other hand, will always represent the entire bounds of your view, regardless of which portion is being redrawn.

Upvotes: 2

ericg
ericg

Reputation: 8732

Most likely your subview has an autoresizing mask. You can clear this by calling -setAutoresizingMask: with NSViewNotSizable.

If the superview should not be resizing any of it's subviews, you could consider using -setAutoresizesSubviews:

Upvotes: 2

Related Questions