3

NSPanelキーウィンドウのときにエスケープキーが閉じないようにする最良の方法を知っている人はいますか? 私のパネルは子ウィンドウであり、ウィンドウの半永久的な部分のように、引き出しのように動作するようにしたいのですが、その中のテキスト コントロールについては、Escape キーで編集をキャンセルしたいと考えています。

最近、Cocoa のドキュメントで Windows と Escape キーに関する詳細を見つけました。NSResponder クラス リファレンスでcancelOperation:は、「ウィンドウがデフォルトのアクション メッセージをcancelOperation:最初のレスポンダーに送信し、そこからメッセージがレスポンダー チェーンを上っていく」と書かれています。の場合は異なるようで、最初の応答者が呼び出しを取得したり、NSTextView デリゲートが呼び出しを取得したりNSPanelすることなく、ウィンドウが閉じます。cancelOperation:doCommandBySelector:

レスポンダチェーンの出入りに関する私の知識は、私がこれまでずっと OS X の仕事をしてきたことを考えると恥ずべきことです。サブクラスで通常のウィンドウのように動作keyDown:させる必要があると考えていました。and can catchNSPanelをオーバーライドして、呼び出しを ではなく に転送しようとしましたが、変更はありませんでした。Escape は、最初の応答者へのメッセージなしでウィンドウを閉じました。それは試してみても合理的でしたか?NSPanelkeyDown:NSWindowkeyDown:super

次に、パネルのサブクラス ' を完全に再実装してkeyDown:、次のようにしました。

[self.firstResponder cancelOperation:self]

これにより、テキスト フィールドが通常どおりにエスケープを処理できるようになると思います。また、テキスト フィールドが最初のレスポンダーではない場合、呼び出しは行き止まりになる可能性があります。しかし、試してみると、パネルは以前と同じように閉じます。明らかに、私は適切なレベルで物事を傍受していません。

cancelOperation:低レベルのキー押下イベントとパネルのクローズの間に実行される一連のメソッド、またはそれをインターセプトしてファーストレスポンダーに確実に送信するためにオーバーライドする必要があるものを誰かが知っていますか?

4

2 に答える 2

0

nib またはコードのどこかで、NSTableView デリゲートをコントローラーに設定します。

setDelegate: は setDatasource: と同じではないことに注意してください。

私の場合: @interface ValueEditor : NSObject

  + (ValueEditorCmdType)cmdTypeForSelector:(SEL)command
  {
     ValueEditorCmdType cmdType = kCmdTypeNone;
     if ( command == @selector(insertLineBreak:) || command == @selector(insertNewline:) || command == @selector(insertNewlineIgnoringFieldEditor:) || command == @selector(insertParagraphSeparator:))
        cmdType = kCmdTypeAccept;
     else if (  command == @selector(insertTab:) || command == @selector(selectNextKeyView:)  || command == @selector(insertTabIgnoringFieldEditor:))
        cmdType = kCmdTypeNext;
     else if ( command == @selector(insertBacktab:) || command == @selector(selectPreviousKeyView:))
        cmdType = kCmdTypePrev;
     else if ( command == @selector(cancelOperation:) )   
        cmdType = kCmdTypeCancel;
     return cmdType;
  }

  #pragma mark - NSControl delegate
  - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
  {
     ValueEditorCmdType cmdType = [ValueEditor cmdTypeForSelector:command];
     if ( cmdType == kCmdTypeCancel )
     {
        [control abortEditing];  

        // when user hits 'ESC' key with a field editor active, cancel the field editor,
        // but return YES here so that NSPanel doesn't close.  
        // Hitting 'ESC' a 2nd time will close the NSPanel.
        return YES;
     }
     return NO;
  }
于 2013-03-26T21:41:08.073 に答える