Programmatically closing an NSWindow when it loses focus - cocoa

I am making an image picker that will display an n by n grid of selectable button when the picker is popped up. This grid of buttons will be contained within an NSWindow but I would like for the window to be close automatically if the user clicks off the screen. Is there a flag that can be set so that when the window looses focus it will be closed automatically?

There are two notifications that you may be interested in: NSWindowDidResignKeyNotification and NSWindowDidResignMainNotification. You can simply register for the one you're interested in in awakeFromNib (or windowDidLoad if you have a custom controller) and then close or hide the window as appropriate when you receive the notifications.
I won't delve too much into whether or not this is a good idea from UI standpoint. But, it might be a better idea to have either an overlay view or a panel for the functionality you describe.

You might check out NSPanel. It's an NSWindow subclass that will hide itself when the app is in the background, and that behavior sounds very similar to what you are looking for.

Related

How do I display a custom view modally, within an existing window?

I am trying to build a UI with a main window that displays some content, and sometimes slides-in a modal view from the right edge of the window. Interaction with the main content must be blocked while the modal is open; however, clicking the main content should close the modal. Here's a mockup:
Please note the user should see only one window. That is, the modal should be nested inside the main window.
I have very little experience with AppKit and Cocoa in general. My approach so far has been to structure my UI like this:
Root region (NSView)
-> MainRegion (NSView)
-> ModalRegion (NSView; toggle hidden and animate the left edge)
and then add subviews to MainRegion and ModalRegion to display content. The problem is that ModalRegion doesn't absorb input events.
What's the AppKit way to build this kind of UI? I mainly just need to know about how the view hierarchy should be shaped and how to block/absorb input events. I think I can figure out the animations myself. Also, the app targets macOS 10.8+, but answers for more recent versions would be helpful, as well.
It’s not really macOS like UI but there are two approaches you could use. In both cases you would use a transparent view to cover the main window and to dismiss the modal view in case of a mouse click. If you need a shadow overlapping the main window as shown in your mockup you will need to use a window attached to the main window as a child window. If this is not the case it would be enough to work with a view which is attached to the contentView of the main window.
All the best.

Add an NSView around cursor?

Simple question, starting out with macOS stuff – I’d like to create a small radial menu around my cursor, top-most, above whatever application is currently active, whenever a specific mouse button is pressed.
I have the specific mouse button over all application down, but I’m wondering where I need to draw that NSView, i.e. “topmost”. I guess on iOS this would be at the UIWindow level, but would NSWindow be the wrong approach here?
this is purely an opinion-based question, but basically if you want to present any custom content on the desktop, that should use NSWindow, and you can customise the window's content for your wish.
NOTE: you can find more information about the NSWindow class in Apple's Class Reference Docs.

FirstResponder as delegate for NSToolBar

I have a Mac app that consists of a window with a variable number of panes in it, each containing a tableview. The window has a toolbar with buttons, and I want the VC for the currently selected pane to handle validating the toolbar items, as well as being target for their actions.
If I could set first responder as delegate for the toolbar, this would be handled automatically, so my question is if that is possible! I have obviously googled around for this and some articles seem to hint that it is possible, but IB doesn't seem to let me do it.
An NSWindowController subclass would be better suited for this, that is the toolbar's delegate (it's natural role anyway) and can talk with the currently selected pane, using a custom protocol to decide on business logic.
Same goes for the UI/Menu action handlers; the window controller is perfect for this and your design will fit within it well.
It's not really got anything to do with the first responder as you are interested in the currently selected pane, not the first responder.

How make button in NSWindow clickable while a sheet's on top of it

I have created a custom (themed) NSWindow, by creating a borderless window and then recreating all elements of the window border/background inside the content view. I've created the window widgets (close box, zoom box, minimize box) on top of my own fake title bar using -standardWindowButton:forStyleMask:.
Trouble is, when a sheet is presented on top of my custom window (e.g. "save changes...", those buttons do not receive the clicks.
Does anybody know how I can tell NSWindow not to intercept the clicks in my minimize box? It works with a standard NSWindow. When a sheet is up, I can still send both of them to the dock, or zoom the window out.
I thought maybe there's special code in the content view that ignores clicks in subviews while a sheet is up. But it seems as if -hitTest: is called on the content view and returns the minimize widget, but the widget's action never gets triggered.
I guess I could just replace the content view and perform the action in the content view's hitTest if it is the minimize widget ... but that seems a bit ugly.

Dynamically removing and attaching the border on a nswindow

How do I go about adding/removing the window border after it has been created? the window was already designed in interface builder and I would prefer to avoid writing the window purely in code as I am still a long ways before i can say i am experienced with objective-c/cocoa.
Example Program:
a single window with the border initially, a button on it. If you click the button once it makes the boarder disappear and if you click it again then the boarder reappears.
Thanks
As far as I can tell, you can't. You might be able to fake it by taking the content view out of one window and making it be the content view of another window.

Resources