7

アプリケーション全体ですべてのキーボード イベントをトラップする方法はありますか? ユーザーがアプリケーション全体でキーボードを使用して何かを入力しているかどうかを知る必要があります (アプリケーションには複数のビューがあります)。UIWindow をサブクラス化することで touchEvents をキャプチャできましたが、キーボード イベントをキャプチャできませんでした。

4

3 に答える 3

14

NSNotificationCenter を使用する

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: UITextFieldTextDidChangeNotification object: nil];

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(keyPressed:) name: UITextViewTextDidChangeNotification object: nil];

........

-(void) keyPressed: (NSNotification*) notification
{
  NSLog([[notification object]text]);
}
于 2009-08-13T06:46:14.097 に答える
12

ブログで UIEvent のちょっとしたハックを使ってイベントをキャッチする方法について書きました

詳細については、「 iOS でキーボード イベントをキャッチする」を参照し  てください。

上記ブログより:

その秘訣は、GSEventKey 構造体メモリに直接アクセスし、特定のバイトをチェックして、押されたキーのキーコードとフラグを知ることです。以下のコードはほとんど自明であり、UIApplication サブクラスに配置する必要があります。

#define GSEVENT_TYPE 2
#define GSEVENT_FLAGS 12
#define GSEVENTKEY_KEYCODE 15
#define GSEVENT_TYPE_KEYUP 11

NSString *const GSEventKeyUpNotification = @"GSEventKeyUpHackNotification";

- (void)sendEvent:(UIEvent *)event
{
    [super sendEvent:event];

    if ([event respondsToSelector:@selector(_gsEvent)]) {

        // Key events come in form of UIInternalEvents.
        // They contain a GSEvent object which contains 
        // a GSEventRecord among other things

        int *eventMem;
        eventMem = (int *)[event performSelector:@selector(_gsEvent)];
        if (eventMem) {

            // So far we got a GSEvent :)

            int eventType = eventMem[GSEVENT_TYPE];
            if (eventType == GSEVENT_TYPE_KEYUP) {

                // Now we got a GSEventKey!

                // Read flags from GSEvent
                int eventFlags = eventMem[GSEVENT_FLAGS];
                if (eventFlags) { 

                    // This example post notifications only when 
                    // pressed key has Shift, Ctrl, Cmd or Alt flags

                    // Read keycode from GSEventKey
                    int tmp = eventMem[GSEVENTKEY_KEYCODE];
                    UniChar *keycode = (UniChar *)&tmp;

                    // Post notification
                    NSDictionary *inf;
                    inf = [[NSDictionary alloc] initWithObjectsAndKeys:
                      [NSNumber numberWithShort:keycode[0]],
                      @"keycode",
                      [NSNumber numberWithInt:eventFlags], 
                      @"eventFlags",
                      nil];
                    [[NSNotificationCenter defaultCenter] 
                        postNotificationName:GSEventKeyUpNotification 
                                      object:nil
                                    userInfo:userInfo];
                }
            }
        }
    }
}
于 2012-01-14T14:28:43.020 に答える
2

簡単な答えではありませんが、2 つのアプローチが利用できると思います。

  1. UIWindow で行ったように、入力コンポーネント (UITextView、UITextField など) をサブクラス化します。

  2. アプリケーション全体の UITextViewDelegate (および UITextFieldDelegate) を作成し、すべての入力フィールド デリゲートをそれに割り当てます。

于 2009-08-12T18:11:31.767 に答える