私は同様の問題を抱えていました。呼び出した後-[NSView enterFullScreenMode:withOptions:]
、全画面表示をクリックするまで、すべての keyDown: イベント (具体的には Escape キーを押す) を受け取ることができませんでした。
にシンボリック ブレークポイントを設定して問題を追跡した-[NSResponder doCommandBySelector:]
ところ、スタック トレースが表示されました。
-[NSApplication sendEvent:]
-[NSWindow sendEvent:]
-[NSWindow keyDown:]
-[NSWindow doCommandBySelector:]
-[NSResponder doCommandBySelector:]
この時点で、keyDown イベントを処理できるオブジェクトがないことを示すシステム ビープ音が再生されました。
アセンブリの出力を見ると、ウィンドウのキーとメインのステータスをチェックしていたことがわかりました。根本的な問題は、(ビューが AppKit によってアタッチされている) プライベート フルスクリーン ウィンドウが自動的にメイン ウィンドウまたはキー ウィンドウにならないため、期待どおりにキー イベントを受信しないことでした。
修正は、 を呼び出し-makeKeyAndOrderFront:
た後にプライベート フルスクリーン ウィンドウで呼び出すこと-[NSView enterFullScreenMode:withOptions:]
でした。
ビューのプロパティが (元のウィンドウではなく) プライベート フルスクリーン ウィンドウに設定されるのは-[NSObject performSelector:withObject:afterDelay:]
、実行ループの次の反復までではないため、これは使用していました。window
プライベート ウィンドウを参照する別の方法がわかりません。
[self.view.window performSelector:@selector(makeKeyAndOrderFront:)
withObject:nil
afterDelay:0];
フル スクリーン モードでのNSView
動作は、AppKit が元のウィンドウからビューを削除し、それをcontentView
プライベート ウィンドウのタイプとして設定することによって機能します_NSFullScreenWindow
(特に、タイトル バーはありません)。Debug > View Debugging > Capture View Hierarchy
これは、ビューがフル スクリーン モードのときに を選択すると表示されます。全画面表示を終了すると、 から削除され、元のウィンドウの_NSFullScreenWindow
として設定されcontentView
ます。
編集:
キーイベントの処理方法を再構成した後、機能しなくなったため、上記の以前の修正を削除しました。アプリの主要なイベントは、カスタム NSView サブクラスであるウィンドウのコンテンツ ビューを介して処理されるようになりました。contentView は、ウィンドウinitialResponder
とfirstResponder
アプリの起動時に作成されます。これらの両方のウィンドウ プロパティは、呼び出し後に再度設定する必要があります。
-[NSView exitFullScreenModeWithOptions:]
AppKit は全画面処理中にそれらを変更するためです。
キーイベントとフルスクリーンを処理する私の NSView サブクラスでは:
[self exitFullScreenModeWithOptions:nil];
[self.window setInitialResponder:self];
[self.window makeFirstResponder:self];
また、10.9.5 でビューがフル スクリーン モードのときに、キーボード イベントがまだ機能しないという問題にも遭遇しました。
問題は、フルスクリーン モードに使用されるプライベート ウィンドウの次のレスポンダーが、元のウィンドウの次のレスポンダーに設定されていなかったことです。これは、AppKit が 10.11 以降で自動的に行うようにです (10.10 での動作は不明です)。以下は問題を修正しました:
// Get a reference to the window controller from the window BEFORE full screen mode is enabled
// and the view's window is set to the private AppKit "_NSFullScreenWindow" instance.
NSWindowController *windowController = self.window.windowController;
// Enable full screen mode on the view
[self enterFullScreenMode:screen withOptions:opts];
// Compatibility: On 10.9.5 the window controller is not set as the nextResponder on the private full-screen window automatically
// Set the existing window controller as the next responder for the private full screen window to ensure it is placed in the responder chain
[self.window setNextResponder:windowController];