6

iOS 7 ができたので、Apple は からキーボード通知を受け取るオプションを削除したよう-sendEvent:です。これは、すべての重要なイベントをキャプチャしてリモート コンピュータ (VNC クライアントなど) に送信するようなものを書きたいと考えている人にとっては、大きな苦痛です。UIKeyCommand必要な機能を提供しません。Apple に提出された多くのバグ レポートがありますが、彼らは耳を傾けません。バグ レポート Apple は、rdar://14129420 が重複しているため、すべてのレポートを閉じています。

これに対する最善の解決策は何ですか?

4

2 に答える 2

5

少なくともこれらのイベントをプライベート API の方法で取得できましたが、keyup は解放されたキーなどの有用な情報を返しません。多分これはから引っ張ることができるものUIEventですか?

追加する必要があるコードは、次の の定義ですUIPhysicalKeyboardEvent

@interface PhysicalKeyboardEvent : UIEvent {//UIPhysicalButtonsEvent
    int _inputFlags;
    NSString *_modifiedInput;
    NSString *_unmodifiedInput;
    NSString *_shiftModifiedInput;
    NSString *_commandModifiedInput;
    NSString *_markedInput;
    long long _modifierFlags;
    NSString *_privateInput;
}
+ (id)_eventWithInput:(id)arg1 inputFlags:(int)arg2;
@property(retain, nonatomic) NSString *_privateInput; // @synthesize _privateInput;
@property(nonatomic) int _inputFlags; // @synthesize _inputFlags;
@property(nonatomic) long long _modifierFlags; // @synthesize _modifierFlags;
@property(retain, nonatomic) NSString *_markedInput; // @synthesize _markedInput;
@property(retain, nonatomic) NSString *_commandModifiedInput; // @synthesize _commandModifiedInput;
@property(retain, nonatomic) NSString *_shiftModifiedInput; // @synthesize _shiftModifiedInput;
@property(retain, nonatomic) NSString *_unmodifiedInput; // @synthesize _unmodifiedInput;
@property(retain, nonatomic) NSString *_modifiedInput; // @synthesize _modifiedInput;
@property(readonly, nonatomic) long long _gsModifierFlags;
- (void)_privatizeInput;
- (void)dealloc;
- (id)_cloneEvent;
- (_Bool)isEqual:(id)arg1;
- (_Bool)_matchesKeyCommand:(id)arg1;
//- (void)_setHIDEvent:(struct __IOHIDEvent *)arg1 keyboard:(struct __GSKeyboard *)arg2;
@property(readonly, nonatomic) long long _keyCode;
@property(readonly, nonatomic) _Bool _isKeyDown;
- (long long)type;
@end

イベントをリッスンするには、 で次を使用しますUIResponder。レスポンダーがキーである必要があるかどうかはわかりません。

- (id)_keyCommandForEvent:(PhysicalKeyboardEvent *)event {
    //Some reason it gets called twice and it's not because of keyup. Keyup seems to not mention it's original key.
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(processEvent:) withObject:event afterDelay:0];
    return [super _keyCommandForEvent:event];
}
- (void)processEvent:(PhysicalKeyboardEvent *)event {
    NSLog(@"%@", [event _unmodifiedInput]);
    NSLog(@"%d", [event _isKeyDown]);
    NSLog(@"%d", [event _inputFlags]);
    if ([event _isKeyDown] && [[event _unmodifiedInput] isEqualToString:@"s"] && [event _modifierFlags]==206158430208) {
        NSLog(@"Hello");
    }
}

このコードが、少なくともこれを必要とする人々の助けになることを願っています。を使用して、コマンド キー、オプション キー、およびコントロール キーが押されたタイミングを判断できます_modifierFlags。私はそれをあまりいじっていませんが、イベントを取得するための良い方法のようです.

http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.htmlからコードを借りて改善することもできます。他の誰かがより良い方法を見つけたら、投稿してください!

これはプライベート API を使用しているため、すべてを でラップした方がよい場合がありますrespondsToSelector。などのこと_unmodifiedInput

Apple がこれを実装するアプリケーションを受け入れるかどうかはわかりませんので、自己責任で使用してください。

于 2013-09-11T17:35:50.747 に答える
4

UIApplication でこのメソッドをオーバーライドして楽しんでください :)

- (void)handleKeyUIEvent:(UIEvent *)event
{
    size_t s = malloc_size((__bridge const void *)(event));
    NSLog(@"%s enter... %ld", __func__, s);
//    unsigned char *ptr = (unsigned char *)(__bridge void *)event;

    unsigned long *ptr = (unsigned long *)(__bridge void *)event;
//
//#define OFF_KEY_MASK 12
//#define OFF_KEY_SCANCODE 15
//#define OFF_KEY_CHAR 17

//    NSLog(@"type: %lx off: %d", *(ptr + 2), 2);
//    NSLog(@"MASK: %lx off: %d", *(ptr + OFF_KEY_MASK), OFF_KEY_MASK);
//    NSLog(@"SCAN: %lx off: %d", *(ptr + OFF_KEY_SCANCODE), OFF_KEY_SCANCODE);
//    NSLog(@"CHAR: %lx off: %d", *(ptr + OFF_KEY_CHAR), OFF_KEY_CHAR);

    NSLog(@"sizeof unsigned long: %lx", sizeof(unsigned long));

    for (int i = 0; i < s / 4; ++i) {
//        NSLog(@"... [%d] = %x", i, *(unsigned char *)(ptr + i));
        NSLog(@"... [%d] = %lx", i, *(unsigned long *)(ptr + i));
    }

#define OFF_DUMP 8

    unsigned long *dump = (unsigned long *) *(ptr + OFF_DUMP);
    s = malloc_size((const void *)*(ptr + OFF_DUMP));

    NSLog(@"... *[%d] size: %ld", OFF_DUMP, malloc_size((const void *)*(ptr + OFF_DUMP)));

    for (int i = 0; i < s / 4; ++i) {
        NSLog(@"..... [%d] = %lx", i, *(unsigned long *)(dump + i));
    }

    struct objc_super super_data = { self, [UIApplication class] };
    objc_msgSendSuper(&super_data, @selector(handleKeyUIEvent:), event);
//    [super handleKeyUIEvent:event];
}
于 2013-10-18T14:13:27.923 に答える