Vincent Gable’s Blog

April 11, 2008

NSWindow setResizable:

Filed under: Cocoa,MacOSX,Objective-C,Programming,Sample Code | ,
― Vincent Gable on April 11, 2008

-[NSWindow setResizable:(BOOL)] does not exist. But, here is a way to get that effect as long as the window was resizable when created. (I don’t know of a way to make a window resizeable if it was first created unresizeable).

The basic idea is to show/hide the resizing controls, and implement delegate functions that prevent the window from being resized when the resizing controls are hidden.

//show or hide hide the window's resizing controls:
[[window standardWindowButton:NSWindowZoomButton] setHidden:!resizable];
[window setShowsResizeIndicator:resizable];

Note that setShowsResizeIndicator: only shows/hides the resize-indicator in the lower-right of the window. It will not make the window non-resizeable.

To keep the window from being resized when showsResizeIndicator is false, implement the delegate methods:

- (NSSize)windowWillResize:(NSWindow *) window toSize:(NSSize)newSize
{
	if([window showsResizeIndicator])
		return newSize; //resize happens
	else
		return [window frame].size; //no change
}

- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
{
	//let the zoom happen iff showsResizeIndicator is YES
	return [window showsResizeIndicator];
}

No Delegate Hack

Finally, there is a hack that avoids using delegate methods, although I don’t recommend it.

[[window standardWindowButton:NSWindowZoomButton] setHidden:!resizable];
[window setShowsResizeIndicator:resizable];
CGFloat resizeIncrements = resizable ? 1 : MAXFLOAT;
[window setResizeIncrements:NSMakeSize(resizeIncrements, resizeIncrements)];

setResizeIncrements “Restricts the user’s ability to resize the receiver so the width and height change by multiples of width and height increments.” So setting it to MAXFLOAT x MAXFLOAT means that the user can’t resize the window, because they won’t have a big enough screen. Note that this won’t disable the “zoom” function, although the user probably couldn’t use it with the zoom button hidden.

This approach uses slightly fewer lines of code, but it is more brittle and indirect, since it depends on the screen-size, not if the window is (visibly) resizeable. I wouldn’t use it over delegates. But here it is.

5 Comments »

  1. Nice little trick. I searched for this method a few times. Another way is to set both the maximum and minimum size to the current window size:

    [window setMinSize:[window frame].size];
    [window setMaxSize:[window frame].size];

    Just make sure you save the original minSize and maxSize values if you ever want to return to a resizable state…

    Comment by Bwass — July 27, 2008 @ 4:19 am

  2. Thanks a lot. This was a great help. I admit it though. I used the non-recommended hack.

    Comment by john seward — May 12, 2009 @ 1:09 pm

  3. I used the delegate method and I am trying to get only two zoom sizes, a min size and a max size. But when the user trys to resize it only allows those two sizes but it flickers… bummer…

    Comment by rezwits — June 27, 2009 @ 2:25 am

  4. BS.

    [[window standardWindowButton:NSWindowZoomButton] setEnabled:NO];
    [window setStyleMask:window.styleMask^NSResizableWindowMask];

    This is how you do it since Mac OS X 10.0.

    Comment by Giuliano Montecarlo — October 27, 2011 @ 11:16 pm

  5. @BS
    setStyleMask is available only for 10.6 and later

    Comment by Pegas — November 27, 2011 @ 10:01 am

RSS feed for comments on this post.

Leave a comment

Powered by WordPress