iOS开发笔记--keyboard相关

最近一个项目有键盘相关的需求:自定义键盘与系统键盘切换。就将键盘相关的知识点顺了一遍。


一、UITextInputTraits 协议

该协议定义了一些与键盘输入相关的属性。所有支持键盘输入的对象都必须接受这个协议,目的是为了与文本输入管理系统正确地交互。

UITextField 和 UITextView ,UISearchBar都支持该协议。


[plain]  view plain copy
  1. @protocol UITextInputTraits   
  2.   
  3. @optional  
  4.   
  5. @property(nonatomic) UITextAutocapitalizationType autocapitalizationType;   
  6. //  定义输入文本的自动大写类型 default is UITextAutocapitalizationTypeSentences  
  7. @property(nonatomic) UITextAutocorrectionType autocorrectionType;          
  8.  // 定义输入文本的自动更正类型 default is UITextAutocorrectionTypeDefault  
  9. @property(nonatomic) UITextSpellCheckingType spellCheckingType NS_AVAILABLE_IOS(5_0);   
  10. // 定义输入文本的拼写检查类型 default is UITextSpellCheckingTypeDefault;  
  11. @property(nonatomic) UIKeyboardType keyboardType;                           
  12. // 定义键盘类型 default is UIKeyboardTypeDefault  
  13. @property(nonatomic) UIKeyboardAppearance keyboardAppearance;               
  14. // 定义键盘外貌类型 default is UIKeyboardAppearanceDefault  
  15. @property(nonatomic) UIReturnKeyType returnKeyType;                         
  16.   
  17. // 定义键盘returnKey的类型 default is UIReturnKeyDefault (See note under UIReturnKeyType enum)  
  18. @property(nonatomic) BOOL enablesReturnKeyAutomatically;                    
  19. // default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents)  
  20. @property(nonatomic,getter=isSecureTextEntry) BOOL secureTextEntry;        
  21.  // 输入文本是否加密 default is NO  
  22.   
  23. @end   


[plain]  view plain copy
  1. typedef NS_ENUM(NSInteger, UIKeyboardType) {  
  2.     UIKeyboardTypeDefault,                // Default type for the current input method.  
  3.     UIKeyboardTypeASCIICapable,            
  4.  // 字母键盘 Displays a keyboard which can enter ASCII characters, non-ASCII keyboards remain active  
  5.     UIKeyboardTypeNumbersAndPunctuation,  // Numbers and assorted punctuation.  
  6.     UIKeyboardTypeURL,                    // A type optimized for URL entry (shows . / .com prominently).  
  7.     UIKeyboardTypeNumberPad,              // A number pad (0-9). Suitable for PIN entry.  
  8.     UIKeyboardTypePhonePad,               // A phone pad (1-9, *, 0, #, with letters under the numbers).  
  9.     UIKeyboardTypeNamePhonePad,           // A type optimized for entering a person's name or phone number.  
  10.     UIKeyboardTypeEmailAddress,           // A type optimized for multiple email address entry (shows space @ . prominently).  
  11. #if __IPHONE_4_1 <= __IPHONE_OS_VERSION_MAX_ALLOWED  
  12.     UIKeyboardTypeDecimalPad,             // A number pad with a decimal point.  
  13. #endif  
  14. #if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED  
  15.     UIKeyboardTypeTwitter,                // A type optimized for twitter text entry (easy access to @ #)  
  16. #endif  
  17.   
  18.     UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable, // Deprecated  
  19.   
  20. };  

这个属性决定了在输入文本中,是否支持拼写检查。


二、定制键盘


[plain]  view plain copy
  1. @interface UIResponder (UIResponderInputViewAdditions)  
  2.   
  3. // Called and presented when object becomes first responder.  Goes up the responder chain.  
  4. @property (readonly, retain) UIView *inputView NS_AVAILABLE_IOS(3_2);                         
  5. //键盘视图,定制的键盘视图要赋值给该属性  
  6. @property (readonly, retain) UIView *inputAccessoryView NS_AVAILABLE_IOS(3_2);     
  7. //键盘辅助视图,即位于键盘视图上面一些额外的辅助性视图,可在上添加辅助功能键  
  8.   
  9. // If called while object is first responder, reloads inputView and inputAccessoryView.  Otherwise ignored.  
  10. - (void)reloadInputViews NS_AVAILABLE_IOS(3_2);  
  11.   
  12. @end  

UITextField 和 UITextView 都提供了以上方法。


iOS开发笔记--keyboard相关_第1张图片


如上图所示,绿色视图为 inputAccessoryView。下面的是定制的键盘视图

示例代码如下

[plain]  view plain copy
  1.  -  (void)viewDidLoad  
  2. {   
  3.         [super viewDidLoad];  
  4.   
  5.         self.numberTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 120, 280, 80)];  
  6.     self.numberTextField.backgroundColor = [UIColor darkGrayColor];  
  7.     self.numberTextField.delegate = self;  
  8.     self.numberTextField.keyboardType = UIKeyboardTypeNamePhonePad;  
  9.   
  10.         self.numberTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;  
  11.     self.numberTextField.autocorrectionType = UITextAutocorrectionTypeNo;  
  12.     self.numberTextField.spellCheckingType = UITextSpellCheckingTypeNo;  
  13.     self.numberTextField.returnKeyType = UIReturnKeySearch;  
  14.   
  15.         _inputView = [[AZStockKeyboardView alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, 216)];  
  16.     _inputView.delegate = self;  
  17.     self.numberTextField.inputView = _inputView;  
  18.     UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];  
  19.     accessoryView.backgroundColor = [UIColor greenColor];  
  20.     self.numberTextField.inputAccessoryView = accessoryView;  
  21.     [self.view addSubview:self.numberTextField];  
  22. }  


切换系统键盘

[plain]  view plain copy
  1. - (void)customedKeyboardDidChange  
  2. {  
  3.     self.numberTextField.inputView = nil;  
  4.     [self.numberTextField reloadInputViews];  
  5. }  

系统键盘切换定制键盘

[plain]  view plain copy
  1. - (void)systemKeyboardDidChange  
  2. {  
  3.     self.numberTextField.inputView = _inputView;  
  4.     [self.numberTextField reloadInputViews];  
  5. }  

给定制的键盘添加系统键盘按键声音

1.定制键盘视图要继承UIView,接受 UIInputViewAudioFeedback 协议,并实现协议方法

[plain]  view plain copy
  1. @interface AZStockKeyboardView : UIView  
  2. {  
  3.   
  4. }  

[plain]  view plain copy
  1. #pragma mark UIInputViewAudioFeedback protocol methods  
  2.   
  3. - (BOOL)enableInputClicksWhenVisible  
  4. {  
  5.     return YES;  
  6. }  


2.在定制的键盘的按键响应的方法中,调用 [[UIDevice currentDevice] playInputClick]

[plain]  view plain copy
  1. - (void)numberButtonClicked:(id)sender  
  2. {  
  3.     [[UIDevice currentDevice] playInputClick];  
  4. }  


三、改造系统键盘

由于需要定制键盘和系统键盘互相切换,就需要将系统键盘的切换键盘的按键响应我们自己的切换键盘方法。

Apple官方并没有提供这种方法,目前可行的做法是将该按键用我们自己的创建的按键将其覆盖。

UITextEffectsWindow       //键盘所在window

UIPeripheralHostView      //键盘视图所在的父视图  定制的键盘视图,辅助视图都放在这个视图上面

UIKeyboardAutomatic      //键盘视图

UIKeyboardImpl               //自己按英文的意思理解的,键盘的实现视图

UIKeyboardLayoutStar     //自己按英文的意思理解的,键盘的布局视图

UIKBKeyplaneView          //

UIKBKeyView                   //根据description判断,是键盘的功能性按键的视图(除字母,数字之外,类似删除键,空格键等)

以上视图都有层级关系,从上到下,上面的视图是下面视图的父视图

完成覆盖按键的任务,需要获取 UIKeyboardAutomatic 视图,然后把定制的切换按键添加到该视图上



获取系统键盘视图

[plain]  view plain copy
  1. - (UIView *)getSystemKeyboardView  
  2. {  
  3.     UIView *returnView = nil;  
  4.       
  5.     UIWindow *keyboardWindow = nil;  
  6.     for (UIWindow *window in [[UIApplication sharedApplication] windows])  
  7.     {  
  8.         if (![NSStringFromClass([window class]) isEqualToString:NSStringFromClass([UIWindow class])])  
  9.         {  
  10.             keyboardWindow = window;  
  11.             break;  
  12.         }  
  13.     }  
  14.     if (keyboardWindow == nil)  
  15.         return nil;  
  16.   
  17.     for (UIView *firstView in [keyboardWindow subviews])  
  18.     {  
  19.         if ([[firstView description] hasPrefix:@"
  20.         {  
  21.             for (UIView *secondView in [firstView subviews])  
  22.             {  
  23.                 if ([[secondView description] hasPrefix:@"
  24.                 {  
  25.                     returnView = secondView;  
  26.                 }  
  27.             }  
  28.         }  
  29.     }  
  30.       
  31.     return returnView;  
  32. }  

监听键盘事件

[plain]  view plain copy
  1. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];  
  2. ificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];  


向键盘视图上覆盖按键

[plain]  view plain copy
  1. - (void)keyboardDidShow:(id)notification  
  2. {  
  3.     _keyboardDefaultView = [self getSystemKeyboardView];  
  4.     if (_keyboardDefaultView)  
  5.     {  
  6.         _switchNumButton = [UIButton buttonWithType:UIButtonTypeCustom];  
  7.         [_switchNumButton setTitle:@"123" forState:UIControlStateNormal];  
  8.         [_switchNumButton setBackgroundImage:[UIImage imageNamed:@"num.png"] forState:UIControlStateNormal];  
  9.         _switchNumButton.frame = CGRectMake(1, 173, 78, 42);  
  10.         [_switchNumButton addTarget:self action:@selector(changeCutomeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  11.         [_keyboardDefaultView addSubview:_switchNumButton];  
  12.     }  
  13. }  


效果如下:


iOS开发笔记--keyboard相关_第2张图片



注意:由于所有系统键盘都是所有程序共享的,所以在当前界面消失前,或者其他类型的输入视图调用键盘前,要将我们自己定制的按键移除。

否则,从其他应用调用该类型键盘,都可以看到我们定制的按键。

同时也应该在调用键盘前,即键盘弹出时,在用我们定制的按键覆盖之前加限定条件


[plain]  view plain copy
  1. - (void)keyboardDidShow:(id)notification  
  2. {  
  3.     _keyboardDefaultView = [self getSystemKeyboardView];  
  4.     if (_keyboardDefaultView && [_numberTextField isFirstResponder])  
  5.     {  
  6.         _switchNumButton = [UIButton buttonWithType:UIButtonTypeCustom];  
  7.         [_switchNumButton setTitle:@"123" forState:UIControlStateNormal];  
  8.         [_switchNumButton setBackgroundImage:[UIImage imageNamed:@"num.png"] forState:UIControlStateNormal];  
  9.         _switchNumButton.frame = CGRectMake(1, 173, 78, 42);  
  10.         [_switchNumButton addTarget:self action:@selector(changeCutomeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  11.         [_keyboardDefaultView addSubview:_switchNumButton];  
  12.     }  
  13.     else  
  14.     {  
  15.         if (_switchNumButton) {  
  16.             [_switchNumButton removeFromSuperview];  
  17.         }  
  18.     }  

你可能感兴趣的:(IOS)