2009-08-12 85 views
6

是否有無法將所有鍵盤事件鎖定在我的應用程序中?我需要知道用戶是否在我的應用程序中使用鍵盤輸入任何內容(應用程序有多個視圖)。我能夠通過繼承UIWindow捕獲touchEvents,但無法捕獲鍵盤事件。接收iPhone鍵盤事件

回答

13

使用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

不是一個簡單的答案,但我認爲你有兩種方法可用。

  1. 子類的輸入組件(UITextView的,的UITextField等),因爲你已經與一個UIWindow完成。

  2. 創建一個應用程序範圍的UITextViewDelegate(和UITextFieldDelegate)並將所有輸入字段委託分配給它。

+0

這現在有點棘手,涉及很多工作。我希望看到一些應用程序級別的事件捕獲 – iamMobile 2009-08-12 18:46:42

10

我寫了一篇關於使用醒目的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

請參閱[「我怎麼能寫我的答案,正確地鏈接到外部資源?」](http://meta.stackexchange.com/questions/94022/how-could -i-寫我的回答,即鏈接到一個外部的資源,正確)。 – 2012-01-14 17:05:23

+0

我不明白我得到了-1。是的,鏈接是我的博客的一篇文章,但它完全回答了這個問題。它捕獲所有鍵盤事件,包括Shift,Cmd,Ctrl,Alt。如果是因爲使用私有API,我明確表示它是**黑客**。我不是在這裏欺騙任何人。 – nacho4d 2012-01-15 14:49:05

+0

可能因爲你的回答沒有回答這個問題,它只是指向一個可以消失,破碎或者簡單地改變超出這個問題的外部來源。正如安娜李爾指出的那樣,閱讀她指出的部分。下面的答案是遵循的正確規則: - 你解釋鏈接項目的內容(可能省略細節或例子) - 你確定作者(你自己,MSDN等) - 某人可以從中受益在沒有閱讀鏈接項目的情況下回答 - 如果點擊鏈接是值得的,可以包含讓讀者決定的信息 – Coyote 2012-09-04 08:38:43