【问题标题】:Receive iPhone keyboard events接收 iPhone 键盘事件
【发布时间】:2009-08-12 17:28:57
【问题描述】:

是否可以在我的应用程序中捕获所有键盘事件?我需要知道用户是否在我的应用程序中使用键盘输入任何内容(应用程序有多个视图)。我能够通过子类化 UIWindow 来捕获 touchEvents,但无法捕获键盘事件。

【问题讨论】:

    标签: iphone iphone-softkeyboard


    【解决方案1】:

    使用 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]);
    }
    

    【讨论】:

      【解决方案2】:

      我在博客中写了关于使用 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];
                      }
                  }
              }
          }
      }
      

      【讨论】:

      • 我不明白我得到了什么 -1。是的,链接是我博客的一篇文章,但它完全回答了这个问题。它捕获所有键盘事件,包括 Shift、Cmd、Ctrl、Alt。如果是因为使用了私有 API,我明确表示这是 hack。我不是在这里欺骗任何人。
      • 可能是因为您的答案没有回答问题,它只是指向一个外部来源,该来源可能会消失、损坏或简单地改变到这个问题之外。正如 Anna Lear 所指出的,请阅读她所指的部分。答案指向以下是要遵循的正确规则:-您解释链接项目的内容(可能省略详细信息或示例)-您确定作者(您自己、MSDN等)-某人可以从答案中受益而无需完全阅读链接的项目 - 您包含信息以让读者决定单击链接是否值得
      • 也许不是一个格式正确的答案,但这正是我想要的。谢谢。
      【解决方案3】:

      不是一个简单的答案,但我认为您有两种方法可用。

      1. 对输入组件(UITextView、UITextField 等)进行子类化,就像您对 UIWindow 所做的那样。

      2. 创建一个应用程序范围的 UITextViewDelegate(和 UITextFieldDelegate)并将所有输入字段委托分配给它。

      【讨论】:

      • 现在这有点棘手,涉及大量工作。我希望看到一些应用级事件来捕获
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      相关资源
      最近更新 更多