How detect Minimize/Maximize window and do this programmatically. I know that i need use NSWindowdelegate, but:
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowdelegate {
func windowWillMiniaturize(_ notification: Notification) {
print("1")
}
}
This not working. And how to maximize/minimize programmatically have no idea.
It is all in Apples documentation on NSWindowDelegate: https://developer.apple.com/reference/appkit/nswindowdelegate
You can implement in you class that is set as delegate for your window:
func windowWillMiniaturize(Notification)
Tells the delegate that the window is about to be minimized.
func windowDidMiniaturize(Notification)
Tells the delegate that the window has been minimized.
func windowDidDeminiaturize(Notification)
Tells the delegate that the window has been deminimized.
NSWindow has methods - easily to find when visiting the documentation: https://developer.apple.com/reference/appkit/nswindow
You can call from anywhere on your window:
func performMiniaturize(Any?)
Simulates the user clicking the minimize button by momentarily highlighting the button, then minimizing the window.
func miniaturize(Any?)
Removes the window from the screen list and displays the minimized window in the Dock.
func deminiaturize(Any?)
De-minimizes the window.
Related
I am making a mac app using Swift and this app has a custom view (a class extending NSView and overriding its draw method). Now, I want to disable all mouse clicks and mouse drags on this view and pass them on to the other applications running beneath my application.
I have tried the following ways (gleaned from Apple documentation and other SO questions) to disable clicks on my view and nothing worked for me so far:
1. Overriding hitTest inside my custom View class
override func hitTest(_ point: NSPoint) -> NSView? {
let view = super.hitTest(point)
return view == self ? nil : view
}
2. Overriding acceptsFirstMouse inside my custom View class
override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
return false
}
3. Overriding mouseDown in ViewController as well as in my custom View class
override func mouseDown(with event: NSEvent) {
// do nothing
}
4. Overriding mouseDragged in ViewController as well as in my custom View class
override func mouseDragged(with event: NSEvent) {
// do nothing
}
Am I missing something?
This isn't handled at the view level, it's handled at the window level. You can set the ignoresMouseEvents property of the window to true.
The issue is that the Window Server will only dispatch an event to a single process. So, once it has arrived in your app, it's not going to another. And there's no feasible way for your app to forward it along, either.
I am building a macOS menubar app in Swift, using an NSStatusItem, which opens an NSPopover when the NSStatusItem's button is clicked.
How can I also give the NSPopover focus? Currently, the user needs to click on the popover to focus it, but I want to grab focus programmatically.
Thanks in Advance
The solution is to call makeKey() on the owning window.
This can be done either from the main NSApplicationDelegate, e.g.
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Other setup
popover.contentViewController?.view.window?.makeKey()
}
Or from the relevant NSViewController, e.g.
override func viewDidAppear() {
super.viewDidAppear()
view.window?.makeKey()
}
Documentation is here
I would like to hide/close my main app window in func viewDidLoad() and only show/unhide the main window if some event requires it.
I tried self.view.window?.close() but this leaves a white window. I also tried NSApp.hide(nil) but then I can't unhide with NSApp.unhide(nil). Here is some sample code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NSApp.hide(nil)
runTest()
}
func runTest () {
let check = false
if check == false {
NSApp.unhide(nil)
}
}
From the NSWindow documentation
func orderOut(_ sender: Any?)
Removes the window from the screen list, which hides the window.
func makeKeyAndOrderFront(_ sender: Any?)
Moves the window to the front of the screen list, within its level, and makes it the key window; that is, it shows the window.
Hide and Close are two different things:
If the window is the key or main window, the window object immediately behind it is made key or main in its place. Calling orderOut(_:) causes the window to be removed from the screen, but does not cause it to be released. See the close() method for information on when a window is released. Calling orderOut(_:) on a child window causes the window to be removed from its parent window before being removed.
Hiding the application (NSApp.hide(nil) is another different thing: It
Hides all the receiver’s windows, and the next app in line is activated.
I am trying to display a second window after a button click:
var winJ:WinJo // other window NSViewController
#IBAction func BtnNewWin(sender: AnyObject) {
winJ = WinJo()
winJ.showWindow(self)
}
This works fine but I want the new window to be modal. I accomplished this with the Xcode designer but I couldn't figure out how to do this in code.
After I was pointed in the right direction I found the solution to my problem:
NSApp.runModalForWindow(winJ.window!)
Where NSApp is actually the instance of NSApplication.
And very important in the second window:
func windowWillClose(notification: NSNotification) {
NSApp.stopModal()
}
Otherwise your main window will be blocked after closing the second.
I'm developing a simple OSX status / menu bar app using this tutorial: http://footle.org/WeatherBar/
This app is going to have a menu with "Preferences" option, which should open the preferences window.
Since the preferences window is going to be opened rather rarely I would like the window to be created only when needed and then deallocated after closing.
Here is the code for the status menu controller which controls showing and creating the preferences window:
class StatusMenuController: NSObject {
#IBOutlet weak var statusMenu: NSMenu!
var preferencesWindowCtrl: PreferencesWindowController!
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSVariableStatusItemLength)
override func awakeFromNib() {
statusItem.title = "MyApp"
statusItem.menu = statusMenu
preferencesWindowCtrl= PreferencesWindowController()
}
#IBAction func preferencesClicked(sender: NSMenuItem) {
preferencesWindowCtrl.showWindow(nil)
/*
THIS CAUSES THE WINDOW TO BE DEALLOCATED IMMEDIATELY:
let myPrefWindow = PreferencesWindowController()
myPrefWindow.showWindow(nil)
*/
}
#IBAction func quitClicked(sender: NSMenuItem) {
NSApplication.sharedApplication().terminate(self)
}
}
In this code window is instantiated in the the status menu controller awakeFromNib, which is something I wanted to avoid (since it makes the window alive for the whole app lifetime). However, if I create it as a local variable inside preferencesClicked it gets deallocated immediately as this functions exists (not really surprising).
How can I make sure this window gets deallocated after it is closed? I guess setting release when closed = true for that window will not help, since the reference is held by StatusMenuController.