IntefaceBuilderではテキストボックス関連のクラスはすべて NSTextFieldが割り当てられている。
通常の用途ではこれで良いのだが、今回のような用途ではオーバスペックで逆に使いづらい。やりたいのは下記のこと。
・キー文字の表示
・キー入力のハンドリング
・レスポンダーになれる
NSTextFieldの場合、入力された「文字列」を扱うのは便利なのだが「キー値」が扱えない。NSTextFieldの派生クラスを作っても - [NSResponder keyDown:] が呼ばれないから。
NSTextFieldで入力キーを扱う方法には、以前紹介した(ファイル名変更(その4)NSTextFieldでESCキーをハンドリングする CommentsAdd Star)、デリゲートメソッド - [NSTextField control:textView:doCommandBySelector:] があるが、特定の文字だけのハンドリングならともかく、ほとんどすべての文字を対象にするには十分でない。
そこで NSTextFieldではなく、その下請けにあたる NSTextView クラスを試してみる。InterfaceBuilderからは作れないようなので、プログラムコードからインスタンスを生成する。
まず NSTextView のサブクラスを定義する。
TextView.h
@interface TextView : NSTextView
キーイベントをデバッグコンソールへ出力させる。
TextView.m
@implementation TextView
- (void)keyDown:(NSEvent *)theEvent
{
NSLog(@"%@", theEvent);
}
このクラスのインスタンスを AppControllerで作成し、ウィンドウへ貼付ける。
AppController.m
- awakeFromNib
{
_text_view = [[TextView alloc] initWithFrame:NSMakeRect(10,10,100,25)];
[[_window contentView] addSubview:_text_view];
[_window makeFirstResponder:_text_view];
[_text_view insertText:@"Hello"];
}
実行してみよう。
NSTextView の上でキーボードをたたいてみる。
2009-06-22 22:29:20.225 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134100.3 flags=0x20102 win=0x0 winNum=15724 ctxt=0x1515f chars="A" unmodchars="A" repeat=0 keyCode=0
2009-06-22 22:29:21.040 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134101.2 flags=0x20102 win=0x0 winNum=15724 ctxt=0x1515f chars="B" unmodchars="B" repeat=0 keyCode=11
2009-06-22 22:29:23.089 HotkeyUI[7058:10b] NSEvent: type=KeyDown loc=(0,119) time=134103.2 flags=0x100108 win=0x0 winNum=15724 ctxt=0x1515f chars="c" unmodchars="c" repeat=0 keyCode=8
- [NSResponder keyDown:] が呼ばれた。
なお入力された文字は NSTextView には反映されない(何を入力しても初期表示 "Hello"のまま)。今回表示は自前で対処するのでこれは好都合。よしこれで進めていこう。