Skip to content

Instantly share code, notes, and snippets.

@usagimaru
Last active February 26, 2024 23:03
Show Gist options
  • Save usagimaru/ce71759b86965de468bfe2f1616929ed to your computer and use it in GitHub Desktop.
Save usagimaru/ce71759b86965de468bfe2f1616929ed to your computer and use it in GitHub Desktop.
NSWindowController.showWindow(_:)でNSWindowDelegateを再設定しなければならない

NSWindowController.showWindow(_:)でNSWindowDelegateを再設定しなければならない

AppKitのNSWindowControllerをNSWindowDelegateにする場合に、なぜだかデリゲートメソッド一式がコールされない現象に悩まされた。調べても原因がよくわからず、NSWindow.delegateの中身を確認しても正しくNSWindowControllerインスタンスが設定されているので、一体どこで通知不能になっているのかが掴めなかった。

一応解決できた方法としては、NSWindowController.showWindow(_:)をオーバーライドし、superのコール前にデリゲートを再設定してあげることでこのコールされない現象を解消できた。

// MyWindowController.swift

override func showWindow(_ sender: Any?) {
	window?.delegate = self // ここで delegate 再設定しないとダメ
	super.showWindow(sender)
}


// MARK: - NSWindowDelegate

func windowDidBecomeKey(_ notification: Notification) {
	// showWindow(_:) tweak によって正しくコールされるようになる
}
	
func windowDidResignKey(_ notification: Notification) {
	// showWindow(_:) tweak によって正しくコールされるようになる
}

しかしどういうことなのだろうこれは。


NSWindowControllerインスタンスを適切に保持し続けること

これ以外に要確認なポイントとして、NSWindowControllerインスタンスが適切に管理されているかどうかがある。要するにウインドウを表示した後にNSWindowControllerインスタンスが自動解放されてしまっていないかどうかを見た方が良い。適当なクラスでNSWindowControllerを保持するプロパティなり用意して、少なくともウインドウが閉じられるまではコントローラも生存していることを保証しなければならない。

let wc = MyWindowController()
wc.showWindow(nil)

// Store the window controller
self.windowControllers.append(wc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment