2017-01-23 12 views
1

標準メカニズム(completionsForPartialWordRange:indexOfSelectedItem:rangeForUserCompletionなどの実装)を使って補完を実装するNSTextViewサブクラス(Obj-C)があります。以前は、AppKitによって自動的に2つのユーザアクションのいずれかで完了が呼び出されました。 (コマンド期間)、またはesc(エスケープ)を押します。私はちょうど新しい「2016年後半」のMacBook Proに切り替え、同時に10.11から10.12にアップグレードしました。コード補完は私のアプリではもう機能しません。私はちょうどNSBeep()へのコールを受け取ります。レスポンダーチェーンの深いところから誰もそれらのキー押しに反応しません。 NSTextViewcomplete:メソッドは決してヒットしません(デバッガ)。完全なNSTextViewバインディング:MacOSで壊れた10.12?

これはAppleが行った変更のためであると思われます。 complete:https://developer.apple.com/reference/appkit/nstextview/1449359-complete?language=objc)のドキュメントが変更されていることがわかりました。 complete:escによってトリガーされたと言われていましたが、現在はF5によってトリガーされていると言われています(私のマシンでは機能しませんが、ファンクションキーのマッピングは常に奇妙で理解しにくいです。

私は、doCommandForSelector:をオーバーライドして、AppKitが試みているセレクタを印刷してからsuperを呼び出すだけで少し寝返りました。その結果、escを押すと、doCommandForSelector:cancelOperation:cancel:で呼び出され、command-が押されます。今度はcancel:となります。これらのキーはパネルなどを取り消すために使用されているため、ここに含まれるパネルはなく、取り消す操作はありません。

私の質問は次のとおりです。私は単に古い行動を取り戻すために? 10.12以降、言い換えれば、私はまだescとcommand-の両方が必要です。私のアプリでcomplete:を呼び出す。 plistファイルを使ってキーバインドを変更するというAppleの文書が見つかりましたが、それは正しい方法ではないようです。多分私はkeyDown:のオーバーライドを行うべきですが、キーイベントの合体、国際的なキーボードのキーコードの解釈などの複雑さのためにそれらが落胆したと思いました。私の理解は、それは一般にイベント処理に介入するには低すぎる点であるということです。代わりに、私はinterpretKeyEvents:の振る舞いをどうにかして、私がcomplete:にしたいキーをバインドすることになっていると思いますが、コードでそれを行う方法を理解できません。

+0

「keyDown:」については正しい方法ではありません。 Appleのドキュメント(https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html)では、「NSEventの文字メソッドを使用してイベントオブジェクトの文字を抽出できます。これらを解釈して、既知のキーボードアクションに関連付けられているかどうかを確認します。そうであれば、それ自体またはスーパービューで適切なアクションメソッドを呼び出します。 – bhaller

+0

ファンクションキーの代わりにタッチバーがあるため、ファンクションキーのマッピングが変更されたと思います。この文書を見たことがありますか(https://developer.apple。com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TextEditing/TextEditing.html)? 「傍受するキーイベント」では、デリゲートを使用して入力をキャプチャする方法について説明し、textView:doCommandBySelector:を使用してテキストビューの内容を実行します。 – malicedShade

+0

うん、私はその文書を知っている。説明していないように見えるのは、アプリケーションがキーバインディングをどのように変更できるかということです。つまり、私のアプリエスケープ内で 'cancel:'の呼び出しではなく 'complete:'の呼び出しに変換するようにするにはどうすればよいですか?ユーザが〜/ Libraryフォルダのplistでカスタムキーバインディングを定義する方法については言及していますが、コード内の特定のアプリケーション内のバインディングを変更することについては何も表示されません。これは奇妙な見落としのようだ。 – bhaller

答えて

0

ここでは、キーバインディングを機能させるためにkeyDown:を上書きする回答があります。しかし、質問に記載されているように、私はこれが正しい/推奨の方法であるかどうかはわかりません。

- (void)keyDown:(NSEvent *)event 
{ 
    NSString *chars = [event charactersIgnoringModifiers]; 
    NSEventModifierFlags flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask; 

    if ([chars length] == 1) 
    { 
     unichar keyChar = [chars characterAtIndex:0]; 

     if ((keyChar == 0x1B) && (flags == 0)) 
     { 
      // escape key pressed 
      [self doCommandBySelector:@selector(complete:)]; 
      return; 
     } 
     if ((keyChar == '.') && (flags == NSEventModifierFlagCommand)) 
     { 
      // command-. pressed 
      [self doCommandBySelector:@selector(complete:)]; 
      return; 
     } 
    } 

    [super keyDown:event]; 
} 

誰かがより良い回答をしたら、私はそれを選ぶことができます。

0

Sierraでは、キー組み合わせ 'opt-esc'がcomplete:の標準バインドとして 'esc'を置き換えました。ご覧のとおり、変更されていない「esc」はcancelOperation:にバインドされています。私のアプリケーションでは、Appleがそのような迷惑な変更を行う理由があると思われるため、新しい動作を上書きするのではなく、文書化しています。

関連する問題