2011-08-30 18 views
5

私は、タイトルバーを含む背景としてイメージを描画するカスタムウィンドウを使用するOS Xのアプリケーションで作業しています。私はウィンドウを描画するためにthis codeを変更し、[NSWindow standardWindowButton:forStyleMask:]を呼び出して、標準の閉じる、最小化、最大化のボタンを取得しています。NSWindow閉じるボタンをオーバーライド

私のアプリケーションではNSPopoverが使用されていますが、ポップオーバーが開いている間にアプリケーションを閉じるか最小化すると、ポップオーバーを閉じるか、アプリケーションを閉じる代わりにポップオーバー最小化のアニメーションが表示されます。 NSWindowの既定のクローズ/最小化動作をオーバーライドする方法はありますか?オープンなpopoversを先に閉じることはできますか?

ありがとうございます。これは明らかな質問ですが、申し訳ありません。これは初めてOS X SDKを使用しているため、多くの経験がありません。

編集:私はこの投稿を数時間後、私は明白な解決策を持っていたと思った - NSWindowDelegateメソッドを使用します。「windowWillMiniaturize:」と「windowWillCloseを」とそこpopoversを解任。しかし、閉じる/最小化ボタンがポップオーバーを閉じるので、ポップオーバーが開いている場合、これらのデリゲートメソッドは呼び出されないようです。これはステップ1に戻りますが、その動作を知っていれば誰かが問題を理解するのに役立ちます。

また、NSPopoversには別の問題があり、接続されているかどうかわからないので、共通の原因がある場合に備えてここに追加すると考えました。場合によっては、ポップオーバーを解除しようとすると、このエラーが発生します(コンテキストの場合は、ポップオーバーの存在をチェックする関数を呼び出すNSButtonを押していますが、存在する場合は閉じます):

2011-08-30 11:24:08.949 Playground[11194:707] *** Assertion failure in +[NSView _findFirstKeyViewInDirection:forKeyLoopGroupingView:], /SourceCache/AppKit/AppKit-1138/AppKit.subproj/NSView.m:11026 
2011-08-30 11:24:08.950 Playground[11194:707] this method is supposed to only be invoked on top level items 
2011-08-30 11:24:08.958 Playground[11194:707] (
    0 CoreFoundation      0x00007fff873d4986 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff87ac6d5e objc_exception_throw + 43 
    2 CoreFoundation      0x00007fff873d47ba +[NSException raise:format:arguments:] + 106 
    3 Foundation       0x00007fff8950314f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 169 
    4 AppKit        0x00007fff88211064 +[NSView _findFirstKeyViewInDirection:forKeyLoopGroupingView:] + 137 
    5 AppKit        0x00007fff87d1f546 _replacementKeyViewAlongKeyViewPath + 565 
    6 AppKit        0x00007fff87d1f2ff -[NSView nextValidKeyView] + 179 
    7 AppKit        0x00007fff87d1f199 -[NSWindow _selectFirstKeyView] + 714 
    8 AppKit        0x00007fff882361cf _NSWindowRecursiveFindFirstResponder + 164 
    9 AppKit        0x00007fff882395c8 _NSWindowExchange + 79 
    10 AppKit        0x00007fff883a7e3a -[_NSWindowTransformAnimation startAnimation] + 426 
    11 AppKit        0x00007fff87c98bb2 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 592 
    12 AppKit        0x00007fff87c9890f -[NSWindow orderWindow:relativeTo:] + 154 
    13 AppKit        0x00007fff883dfaf0 _NSPopoverCloseAndAnimate + 948 
    14 Playground       0x00000001000078a4 -[MainWindowController dismissPopover:] + 100 
    15 Playgorund       0x0000000100007012 -[MainWindowController requestWasClicked:] + 98 
    16 CoreFoundation      0x00007fff873c411d -[NSObject performSelector:withObject:] + 61 
    17 AppKit        0x00007fff87ca2852 -[NSApplication sendAction:to:from:] + 139 
    18 AppKit        0x00007fff87ca2784 -[NSControl sendAction:to:] + 88 
    19 AppKit        0x00007fff87ca26af -[NSCell _sendActionFrom:] + 137 
    20 AppKit        0x00007fff87ca1b7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014 
    21 AppKit        0x00007fff87d2157c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489 
    22 AppKit        0x00007fff87ca0786 -[NSControl mouseDown:] + 786 
    23 AppKit        0x00007fff87c6b66e -[NSWindow sendEvent:] + 6280 
    24 AppKit        0x00007fff87c03f19 -[NSApplication sendEvent:] + 5665 
    25 AppKit        0x00007fff87b9a42b -[NSApplication run] + 548 
    26 AppKit        0x00007fff87e1852a NSApplicationMain + 867 
    27 Playground       0x0000000100001c52 main + 34 
    28 Playground       0x0000000100001c24 start + 52 
    29 ???         0x0000000000000001 0x0 + 1 
) 

答えて

3

解決策はかなり簡単であることが判明しました。

-(void)closeThisWindow { 
    [self close]; // for the minimize button you'll call [self.window miniaturize] 
} 

[closeButton setTarget:self.delegate]; // alternatively you can make it self.windowController 
[closeButton setAction:@selector(closeThisWindow:)]; 

がその後のNSWindowControllerサブクラスで、私はメソッドを実装し:私はNSWindowの上のボタンを作成したとき

は、私はボタンのアクションとターゲットを変更しましたなんらかの理由で、NSPopoverは、ウィンドウが再オープンまたは最小化されたときに常に再表示されます。実際に私のアプリケーションでこの動作が必要なので、問題はありませんが、このソリューションを使用する場合は注意が必要です。子ウィンドウがない場合は、NSPopoverが子ウィンドウとみなされるため、self.window.childWindowsを反復するだけです。別々に扱いたい子ウインドウがある場合は、NSWindowサブクラスに配列を追加してすべてのポップオーバーを監視し、それを反復することができます。

+0

しかし、スタックトレースはどうですか?私は知る必要がある。 –

+0

@ Big-OClaire残念ながら、この質問は6歳に近づいています。私は実際にはソースコードにアクセスできませんので、お手伝いできません。ごめんなさい! – Aaron

関連する問題