In NSWindow class there is a computed property called isVisible, I am creating a custom NSWindow and i am calling it MyNSWindow so I want look the value change of isVisible for MyNSWindow, for example the value should be false before window get available in screen, and after that the value should be true, so I want observe this value change, how can i do this? Also I am not looking for an answer with Combine.
This is my code:
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
private var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
window = MyNSWindow(
contentRect: NSRect(x: 0, y: 0, width: 100.0, height: 100.0),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.setFrameAutosaveName("Main Window")
window.title = "No Storyboard Window"
window.makeKeyAndOrderFront(window)
window.center()
}
}
class MyNSWindow: NSWindow {
}
>Solution :
Apple has made it difficult to reliably be notified when a window becomes visible or hidden. I’ve done some investigating for my own project, and here’s what I’ve discovered:
-
Apple’s recommended solution is to set an
NSViewControlleras the window’scontentViewController. Override the view controller’sviewWillAppearorviewDidAppearmethod to be notified when the window becomes visible. Override the view controller’sviewWillDisappearorviewDidDisappearmethod to be notified when the window becomes hidden.I know this is Apple’s recommend solution because I opened a feedback (in 2016) requesting a public
windowWillShownotification and was told:Our more modern way of doing this is to use Storyboards with a View Controller; the contentViewController will get a viewWillAppear — this is the hook you should be using now.
As far as I know from very limited testing, this method is reliable, so it may work well for you. I have an existing app with many windows that were implemented without
contentViewControllers that I do not wish to retrofit, so this doesn’t work well for me. Also, you can only apply this to windows you create—not, for example, to the window created byNSAlert. -
visibleis not KVO-compliant. -
There are no documented notifications posted when
visiblechanges fromfalsetotrue. -
The
NSWindow.willCloseNotificationis supposed to be posted whenvisiblechanges fromtruetofalse, but it doesn’t get posted when a window presented as a sheet is dismissed. -
It should be possible to use Cocoa Bindings to bind to
visible(using theNSVisibleBindingconstant), but the binding is not updated when a window presented as a sheet is dismissed. It is also annoying and obscure to implement. -
There is no single, public “funnel” method you can override on
NSWindowto be notified. TheorderOut(_:),orderFront(_:), andorderBack(_:)methods do go throughorder(_:relativeTo:), butorderFrontRegardless()does not. Sheet presentation and dismissal do go throughorder(_:relativeTo:), so if you never useorderFrontRegardless(), making anNSWindowthat overridesorder(_:relativeTo:)may be a good solution for you. You will not, however, be notified of the appearance and disappearance of windows created by AppKit for you, such as the window created byNSAlert. If you create anyNSPanels, you’ll also want to create anNSPanelsubclass. -
AppKit posts a number of undocumented notifications when windows change visibility, that are posted reliably even for sheet presentation and dismissal. Two of these are named
_NSWindowWillBecomeVisibleandNSWindowWillOrderOffScreenNotification. Use at your own risk.