18

In IB this can be done easily by checking the 'Resize' checkbox on or off. My problem is I want my main NSWindow to not be resizable, until a button is clicked, and then i want it to be resizable.

I've scoured the Internet but can't find anything? Can a window not be made to be resizable or not programmatically?

Thanks in advance everyone!

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
Cristian
  • 6,765
  • 7
  • 43
  • 64

6 Answers6

53

Since 10.6, you can change the style mask of a window using -[NSWindow setStyleMask:]. So, you'd do something like this:

In Objective-C

To make it resizable:

window.styleMask |= NSWindowStyleMaskResizable;

To make it non-resizable:

window.styleMask &= ~NSWindowStyleMaskResizable;

In Swift

To make it resizable:

mainWindow.styleMask = mainWindow.styleMask | NSWindowStyleMaskResizable

To make it non-resizable:

mainWindow.styleMask = mainWindow.styleMask & ~NSWindowStyleMaskResizable
Léo Natan
  • 56,823
  • 9
  • 150
  • 195
Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • perfect thanks, I take it that makes the window resizable? how would I then make it non-resizable? thanks for your help! – Cristian May 06 '12 at 20:48
  • 2
    For Swift 3, put this code in viewDidAppear: view.window!.styleMask.remove(NSWindowStyleMask.resizable) – balazs630 Feb 17 '17 at 22:40
  • 6
    A more readable Swift version would be `mainWindow.styleMask.insert(.resizable)` or, respectively, `mainWindow.styleMask.remove(.resizable)`. You can read more about SetAlgebra here: https://developer.apple.com/documentation/swift/setalgebra – iStefo Feb 26 '19 at 12:59
10

The Swift 3 solution to this issue is to use the OptionSet class described at:

https://developer.apple.com/reference/swift/optionset

In short:

To replace the set of flags, you now do something like:

myWindow.styleMask = [ .resizable, .titled, .closable ]

To add a flag, do something like:

myWindow.styleMask.insert( [ .miniaturizable, .fullscreen ] )

To remove a flag, something like:

myWindow.styleMask.remove( [ .resizable ] )
uliwitness
  • 8,532
  • 36
  • 58
4

You can't change the style mask of a window after creating it, but you can set the window's minimum and maximum frame size to the same size. Do that after you and your resizable window awake from nib, and then change the maximum and optionally the minimum size back when the user clicks the button.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • What do you mean? I successfully used Ken's code at `windowDidLoad` message – Mugen Aug 20 '15 at 05:21
  • 1
    My knowledge must have been out of date! There totally is a `setStyleMask:` method now. https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/#//apple_ref/occ/instm/NSWindow/setStyleMask: – Peter Hosey Aug 21 '15 at 05:15
4

In Swift 3,

if enabled {
  window.styleMask.update(with: .resizable)
} else {
  window.styleMask.remove(.resizable)
}
onmyway133
  • 45,645
  • 31
  • 257
  • 263
1

In Xcode 8 / Swift 3, try something like:

// e.g., on a view controller’s viewDidAppear() method:
if let styleMask = view.window?.styleMask
{
    view.window!.styleMask = NSWindowStyleMask(rawValue: styleMask.rawValue | NSWindowStyleMask.resizable.rawValue)
}
Aral Balkan
  • 5,981
  • 3
  • 21
  • 24
0

I am new to macOS development. None of the above solutions worked for me (Swift 4.2). I also didn't learn that much (copy/paste doesn't help with that).

I have created this NSWindow subclass. I use it in Interface builder.

class MainDocumentChooserW: NSWindow {

    // NOTE: This method is called when the Window is used via Interface builder.
    // Setting the styleMask like this will override the IB settings.
    override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
        super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag)
        styleMask = [.miniaturizable, .titled, .closable]
    }
}

Tested on macOS: High Sierra 10.13.6 (17G5019).

Darkwonder
  • 1,149
  • 1
  • 13
  • 26