【发布时间】:2009-08-12 17:28:57
【问题描述】:
是否可以在我的应用程序中捕获所有键盘事件?我需要知道用户是否在我的应用程序中使用键盘输入任何内容(应用程序有多个视图)。我能够通过子类化 UIWindow 来捕获 touchEvents,但无法捕获键盘事件。
【问题讨论】:
标签: iphone iphone-softkeyboard
是否可以在我的应用程序中捕获所有键盘事件?我需要知道用户是否在我的应用程序中使用键盘输入任何内容(应用程序有多个视图)。我能够通过子类化 UIWindow 来捕获 touchEvents,但无法捕获键盘事件。
【问题讨论】:
标签: iphone iphone-softkeyboard
使用 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]);
}
【讨论】:
我在博客中写了关于使用 UIEvent 的小技巧来捕获事件的文章
请参考: Catching Keyboard Events in 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];
}
}
}
}
}
【讨论】:
不是一个简单的答案,但我认为您有两种方法可用。
对输入组件(UITextView、UITextField 等)进行子类化,就像您对 UIWindow 所做的那样。
创建一个应用程序范围的 UITextViewDelegate(和 UITextFieldDelegate)并将所有输入字段委托分配给它。
【讨论】: