Non-resizable window swift
Asked Answered
F

6

15

I have a NSViewController named Hardness, and I need not to let user resize it. Of course, I can just resize it back every time the users tries, but is there any way just not to let user open a window to full screen, or to stretch the window?

Frisby answered 30/3, 2015 at 5:15 Comment(0)
R
23

edit/update: Xcode 10.2 • Swift 5

NSWindow has a property called styleMask that allows you to control what kinds of control will be available to the user. If you don't want to allow the user to resize the window you have to remove the style mask .resizable using the mutating method remove(member: NSWindowStyleMask). To enable it again you need to use the mutating method insert(member: NSWindowStyleMask). Note that it will also disable the full screen mode for that window:


removing to disable:

window.styleMask.remove(.resizable)

inserting to enable

window.styleMask.insert(.resizable)

Sample

import Cocoa
class ViewController: NSViewController {
    @IBOutlet weak var closable: NSButton!
    @IBOutlet weak var miniaturizable: NSButton!
    @IBOutlet weak var resizable: NSButton!
    @IBOutlet weak var titled: NSButton!
    lazy var window: NSWindow! = self.view.window
    func remove(_ member: NSWindow.StyleMask) {
        window.styleMask.remove(member)
    }
    func insert(_ member: NSWindow.StyleMask) {
        window.styleMask.insert(member)
    }
    @IBAction func toggle(_ sender: NSButton) {
        switch sender.state {
        case .on:
            switch sender {
            case closable: insert(.closable)
            case miniaturizable: insert(.miniaturizable)
            case resizable: insert(.resizable)
            case closable: insert(.closable)
            case titled: insert(.titled)
            default: break
            }
        case .off:
            switch sender {
            case closable: remove(.closable)
            case miniaturizable: remove(.miniaturizable)
            case resizable: remove(.resizable)
            case closable: remove(.closable)
            case titled: remove(.titled)
            default: break
            }
        default: break
        }
    }
}

Sample Project

Rhodos answered 30/3, 2015 at 6:0 Comment(3)
I've written in the viewDidLoad this code: self.view.window?.styleMask = NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask and that didn't workFrisby
Oh, this code needs to be in viewDidAppear, that worked, thank you!Frisby
window.styleMask = [.closable, .titled, .miniaturizable] //Swift 3Therapist
U
12

I solved the same issue with the non-resizable window by one line of code in

override func viewDidAppear() {
    self.view.window?.styleMask.remove(NSWindowStyleMask.Resizable)
}
Uranography answered 18/9, 2016 at 11:17 Comment(1)
I like that better.Continuo
O
6

The correct approach would be to use bitwise operators.

Disable resize:

window?.styleMask &= ~NSResizableWindowMask

Enable resize:

window?.styleMask |= NSResizableWindowMask
Oculus answered 7/4, 2016 at 15:10 Comment(3)
Hi. Any ideas how to port it to Swift 3? Binary operator '|=' cannot be applied to two 'NSWindowStyleMask' operandsStaphylococcus
I don't know why this is so, but here is a workaround: window?.styleMask = NSWindowStyleMask(rawValue: (NSWindowStyleMask.closable.rawValue | NSWindowStyleMask.titled.rawValue))Continuo
It will be window?.styleMask.update(with: NSWindowStyleMask.resizable).Cuirassier
C
2

This answer may be of some help in addition to the current one. There's also a nice simple way to accomplish this by using setHidden with NSWindowZoomButton

Setup the functionality as a sub-class of NSWindow:

Objective-C

#import "CustomWindow.h"

@implementation CustomWindow

- (void)awakeFromNib {

NSButton *zoomButton = [self standardWindowButton:NSWindowZoomButton];
[zoomButton setHidden:YES];

}

@end

Swift

import CustomWindow

class CustomWindow {

    func awakeFromNib() {
        var zoomButton: NSButton = self.standardWindowButton(NSWindowZoomButton)
        zoomButton.setHidden(true)
    }
}

Connect the custom class to your window in IB and the Zoom button should be now hidden!

Caracal answered 31/10, 2015 at 23:10 Comment(7)
shouldnt it be? class CustomWindow: NSWindow { override func awakeFromNib() { var zoomButton: NSButton = self.standardWindowButton(NSWindowButton.ZoomButton)! zoomButton.enabled=true } } i tried to do the same for close button but it wouldnt work..Tart
@Do2: Try using self.standardWindowButton(NSWindowButton.CloseButton)?.hidden = true ... I think apple changed it up a bit since I answered this question originally.Happiness
var closeButton: NSButton = self.standardWindowButton(NSWindowButton.CloseButton)! closeButton.hidden=true ? I also tried to call the awakefromnib from the viewDidAppear of the viewcontroller from the view It crashes due to nil while unwrapping an optional, any ideas?Tart
Are you trying to hide the zoom button or close button? and in what version of swift, and OS X are you using? I'll post a more complete gist you can try shortly.Happiness
im using modal views so the close button disappears after the first segue, and then after 2-3 segues the minimise and resize are hidden but if you hover over them they show up, i would like all the buttons to be shown no matter how many segues are performed. swift 2.2 el capitanTart
@Do2: I hadn't done this with storyboards before, ( usually just nibs ) so I would recommend trying something like this with your windowcontroller: gist.github.com/anonymous/86596332f570ecbf2452b90077197264Happiness
Let us continue this discussion in chat.Tart
C
2

A little more elegant solution for Swift 3, so that the | operator can be used:

public func | (left: NSWindowStyleMask, right: NSWindowStyleMask) -> NSWindowStyleMask {
    return NSWindowStyleMask(rawValue: left.rawValue | right.rawValue)
}
Continuo answered 17/9, 2016 at 22:33 Comment(0)
O
0

For those using SwiftUI, who don't have access to viewDidAppear, you can do this in your app delegate to disable window resizing for all windows:

final class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        NSApp.windows.forEach { $0.styleMask.remove(.resizable) }
    }
}

(And, of course, you can filter NSApp.windows if you want to apply this to a single window.)

Otti answered 12/4 at 12:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.