如何從iOS應用程式的自定義鍵盤檢索擊鍵?
主題專注於自定義鍵盤的視覺元素,但我正在努力瞭解如何從這個鍵盤中檢索擊鍵.
Apple提供了inputView機制,可以輕鬆地將自定義鍵盤與UITextField或UITextView相關聯,但它們不提供將生成的擊鍵傳送回相關物件的功能.基於這些物件的典型委託,我們期望三個函式:一個正常字元,一個用於退格,一個用於輸入.然而,沒有人似乎明確界定這些功能或如何使用它們.
如何為我的iOS應用程式建立自定義鍵盤並從中檢索擊鍵?
格雷格的方法應該是有效的,但我有一種方法,不需要關於文字欄位或文字檢視的鍵盤.實際上,您可以建立鍵盤的單個例項並將其分配到多個文字欄位和/或文字檢視.鍵盤處理知道哪一個是第一個響應者.
這是我的做法我不會顯示用於建立鍵盤佈局的任何程式碼.這很簡單.此程式碼顯示所有管道.
編輯:這已經更新,以正確處理UITextFieldDelegate textField:shouldChangeCharactersInRange:replacementString:和UITextViewDelegate textView:shouldChangeTextInRange:replacementText :.
標頭檔案:
@interface SomeKeyboard : UIView <UIInputViewAudioFeedback> @end
執行檔案:
@implmentation SomeKeyboard { id<UITextInput> _input; BOOL _tfShouldChange; BOOL _tvShouldChange; } - (id)init { self = [super init]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkInput:) name:UITextFieldTextDidBeginEditingNotification object:nil]; } return self; } // This is used to obtain the current text field/view that is now the first responder - (void)checkInput:(NSNotification *)notification { UITextField *field = notification.object; if (field.inputView && self == field.inputView) { _input = field; _tvShouldChange = NO; _tfShouldChange = NO; if ([_input isKindOfClass:[UITextField class]]) { id<UITextFieldDelegate> del = [(UITextField *)_input delegate]; if ([del respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { _tfShouldChange = YES; } } else if ([_input isKindOfClass:[UITextView class]]) { id<UITextViewDelegate> del = [(UITextView *)_input delegate]; if ([del respondsToSelector:@selector(textView:shouldChangeTextInRange:replacementText:)]) { _tvShouldChange = YES; } } } } // Call this for each button press - (void)click { [[UIDevice currentDevice] playInputClick]; } // Call this when a button on the keyboard is tapped (other than return or backspace) - (void)keyTapped:(UIButton *)button { NSString *text = ???; // determine text for the button that was tapped if ([_input respondsToSelector:@selector(shouldChangeTextInRange:replacementText:)]) { if ([_input shouldChangeTextInRange:[_input selectedTextRange] replacementText:text]) { [_input insertText:text]; } } else if (_tfShouldChange) { NSRange range = [(UITextField *)_input selectedRange]; if ([[(UITextField *)_input delegate] textField:(UITextField *)_input shouldChangeCharactersInRange:range replacementString:text]) { [_input insertText:text]; } } else if (_tvShouldChange) { NSRange range = [(UITextView *)_input selectedRange]; if ([[(UITextView *)_input delegate] textView:(UITextView *)_input shouldChangeTextInRange:range replacementText:text]) { [_input insertText:text]; } } else { [_input insertText:text]; } } // Used for a UITextField to handle the return key button - (void)returnTapped:(UIButton *)button { if ([_input isKindOfClass:[UITextField class]]) { id<UITextFieldDelegate> del = [(UITextField *)_input delegate]; if ([del respondsToSelector:@selector(textFieldShouldReturn:)]) { [del textFieldShouldReturn:(UITextField *)_input]; } } else if ([_input isKindOfClass:[UITextView class]]) { [_input insertText:@"\n"]; } } // Call this to dismiss the keyboard - (void)dismissTapped:(UIButton *)button { [(UIResponder *)_input resignFirstResponder]; } // Call this for a delete/backspace key - (void)backspaceTapped:(UIButton *)button { if ([_input respondsToSelector:@selector(shouldChangeTextInRange:replacementText:)]) { UITextRange *range = [_input selectedTextRange]; if ([range.start isEqual:range.end]) { UITextPosition *newStart = [_input positionFromPosition:range.start inDirection:UITextLayoutDirectionLeft offset:1]; range = [_input textRangeFromPosition:newStart toPosition:range.end]; } if ([_input shouldChangeTextInRange:range replacementText:@""]) { [_input deleteBackward]; } } else if (_tfShouldChange) { NSRange range = [(UITextField *)_input selectedRange]; if (range.length == 0) { if (range.location > 0) { range.location--; range.length = 1; } } if ([[(UITextField *)_input delegate] textField:(UITextField *)_input shouldChangeCharactersInRange:range replacementString:@""]) { [_input deleteBackward]; } } else if (_tvShouldChange) { NSRange range = [(UITextView *)_input selectedRange]; if (range.length == 0) { if (range.location > 0) { range.location--; range.length = 1; } } if ([[(UITextView *)_input delegate] textView:(UITextView *)_input shouldChangeTextInRange:range replacementText:@""]) { [_input deleteBackward]; } } else { [_input deleteBackward]; } [self updateShift]; } @end
此類需要UITextField的類別方法:
@interface UITextField (CustomKeyboard) - (NSRange)selectedRange; @end @implementation UITextField (CustomKeyboard) - (NSRange)selectedRange { UITextRange *tr = [self selectedTextRange]; NSInteger spos = [self offsetFromPosition:self.beginningOfDocument toPosition:tr.start]; NSInteger epos = [self offsetFromPosition:self.beginningOfDocument toPosition:tr.end]; return NSMakeRange(spos, epos - spos); } @end
http://stackoverflow.com/questions/13205160/how-do-i-retrieve-keystrokes-from-a-custom-keyboard-on-an-ios-app