一.键盘通知
当文本View(如UITextField,UITextView, UIWebView内的输入框)进入编辑模式成为first responder时,系统会自动显示键盘。成为firstresponder可能由用户点击触发,也可向文本View发送becomeFirstResponder消息触发。当文本视图退出first responder时,键盘会消失。文本View退出first responder可能由用户点击键盘上的Done或Return键结束输入触发,也可向文本View发送resignFirstResponder消息触发。
当键盘显示或消失时,系统会发送相关的通知:
UIKeyboardWillShowNotifi
UIKeyboardDidShowNotific
UIKeyboardWillHideNotifi
UIKeyboardDidHideNotific
通知消息 NSNotification中的 userInfo字典中包含键盘的位置和大小信息,对应的key为
UIKeyboardFrameBeginUser
UIKeyboardFrameEndUserIn
UIKeyboardAnimationDurat
UIKeyboardAnimationCurve
UIKeyboardFrameBeginUser
UIKeyboardAnimationCurve
UIKeyboardAnimationDurat
例如,在UIKeyboardWillShowNotifi
userInfo = { UIKeyboardAnimationCurve UserInfoKey = 0; UIKeyboardAnimationDurat ionUserInfoKey = "0.25"; UIKeyboardBoundsUserInfo Key = "NSRect: {{0, 0}, {320, 216}}"; UIKeyboardCenterBeginUse rInfoKey = "NSPoint: {160, 588}"; UIKeyboardCenterEndUserI nfoKey = "NSPoint: {160, 372}"; UIKeyboardFrameBeginUser InfoKey = "NSRect: {{0, 480}, {320, 216}}"; UIKeyboardFrameChangedBy UserInteraction = 0; UIKeyboardFrameEndUserIn foKey = "NSRect: {{0, 264}, {320, 216}}"; }
在UIKeyboardWillHideNotifi
userInfo内容为:
userInfo = { UIKeyboardAnimationCurve UserInfoKey = 0; UIKeyboardAnimationDurat ionUserInfoKey = "0.25"; UIKeyboardBoundsUserInfo Key = "NSRect: {{0, 0}, {320, 216}}"; UIKeyboardCenterBeginUse rInfoKey = "NSPoint: {160, 372}"; UIKeyboardCenterEndUserI nfoKey = "NSPoint: {160, 588}"; UIKeyboardFrameBeginUser InfoKey = "NSRect: {{0, 264}, {320, 216}}"; UIKeyboardFrameChangedBy UserInteraction = 0; UIKeyboardFrameEndUserIn foKey = "NSRect: {{0, 480}, {320, 216}}"; }
在Text,Web, and Editing Programming Guide for iOS中,有如下描述Note: The rectangle contained in the UIKeyboardFrameBeginUser
但从实际获取的信息来看,矩形的origin并不为{0.0, 0.0},这里应该不准确。
二.文本对象与WebView键盘设置
UITextFiled和 UITextView都遵循 UITextInputTraits协议,在UITextInputTraits协议中定义了设置键盘的属性,有
1. keyboardType:键盘类型,如UIKeyboardTypeDefault,UIKeyboardTypeURL,UIKeyboardTypeEmailAddre
2. returnKeyType:键盘Return键显示的文本,默认为”Return”,其他可选择的包括Go,Next,Done,Send,Google等。
3. keyboardAppearance:键盘外观,默认为 UIKeyboardAppearanceDefa
键盘背景为黑色半透明,用于在警告框输入时显示,例如appStore中输入密码时:
若想显示黑色键盘又不想透明露出底部视图,可以将键盘配置成Alert类型的,然后监听键盘显示的广播通知,在显示键盘时在键盘底部增加一不透明黑色背景视图。
注:在苹果的键盘示例程序 KeyboardAccessory中,将UITextView键盘类型更改为UIKeyboardAppearanceAler
4.autocapitalizationType:文本大小写样式,见 UITextAutocapitalization
5.autocorrectionType:是否自动更正,见 UITextAutocorrectionType
6.spellCheckingType:拼写检查设置,见UITextSpellCheckingType。
7. enablesReturnKeyAutomati
8. secureTextEntry:若输入的是密码,可设置此类型为YES,输入字符时可显示最后一个字符,其他字符显示为点。
UIWebView本身不直接遵循 UITextInputTraits协议,但同样可设置其内部输入部件的键盘属性。如Configuring the Keyboard for Web Views中所述。
设置autocorrect, auto-capitalization属性。
设置键盘类型:
Text:
Telephone: URL: Email: Zip code:
三. 使用键盘通知调整文本视图位置
当文本视图成为First Responser时在窗口底部会显示出键盘,显示的键盘很可能会将文本视图盖住从而无法看到编辑的效果。键盘通知的一大用途即在键盘显示或隐藏时获取到键盘的位置信息,从而可以调整窗口中的文本视图位置或大小,使其可以在键盘上方显示。
Text, Web, and Editing Programming Guide for iOS中的Moving
Content That Is Located Under the Keyboard节在键盘显示和消失通知中,通过调整内容UIScrollView视图的contentInset和 contentOffset来保证编辑的文本视图不会被键盘盖住。
其流程为
1.在初始化( viewDidLoad或viewWillAppear)时,注册处理键盘通知的方法。
- (void)registerForKeyboardNotif ications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotific ation object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotifi cation object:nil]; }
2.在键盘显示的通知事件处理中获取到即将显示键盘的大小,将 UIScrollView的contentInset设置为键盘的frame区域,同样设置scrollIndicatorInsets保证滚动条不会被键盘盖住。获取到编辑文本视图的原点位置,与键盘显示区域比较,若会被键盘覆盖,则调整 contentOffset以使其在键盘上方
// Called when the UIKeyboardDidShowNotific ation is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUser InfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it's visible // Your application might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) { CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height); [scrollView setContentOffset:scrollPoint animated:YES]; } }
3.在键盘消失的通知处理事件中,简单的将UIScrollView恢复即可
// Called when the UIKeyboardWillHideNotifi cation is sent - (void)keyboardWillBeHidden:(NSNotification*)aNotification { UIEdgeInsets contentInsets = UIEdgeInsetsZero; scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; }
在苹果的 KeyboardAccessory示例程序中同样演示了使用键盘通知来调整文本视图位置的代码,其中使用了键盘通知中的键盘动画时间,从而使文本视图移动的动画与键盘的显示和消失同步。
- (void)keyboardWillShow:(NSNotification *)notification { NSDictionary *userInfo = [notification userInfo]; // Get the origin of the keyboard when it's displayed. NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserIn foKey]; // Get the top of the keyboard as the y coordinate of its origin in self's view's coordinate system. The bottom of the text view's frame should align with the top of the keyboard's final position. CGRect keyboardRect = [aValue CGRectValue]; keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; CGFloat keyboardTop = keyboardRect.origin.y; CGRect newTextViewFrame = self.view.bounds; newTextViewFrame.size.height = keyboardTop - self.view.bounds.origin.y; // Get the duration of the animation. NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurat ionUserInfoKey]; NSTimeInterval animationDuration; [animationDurationValue getValue:&animationDuration]; // Animate the resize of the text view's frame in sync with the keyboard's appearance. [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:animationDuration]; textView.frame = newTextViewFrame; [UIView commitAnimations]; } - (void)keyboardWillHide:(NSNotification *)notification { NSDictionary* userInfo = [notification userInfo]; NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurat ionUserInfoKey]; NSTimeInterval animationDuration; [animationDurationValue getValue:&animationDuration]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:animationDuration]; textView.frame = self.view.bounds; [UIView commitAnimations]; }
关于调整文本视图大小的代码,还可以参考Different way to show keyboard and resize UIView with text field。
还可以在键盘通知中实现自定义键盘,例如UIKEYBOARDTYPENUMBERPAD AND THE MISSING “RETURN” KEY中使用键盘通知在数字键盘中增加Return键,还可参考UIKeyboardTypeNumberPad键盘增加Return键
注:若在同一窗口中有两个UITextField,当第一个UITextField成为First Responser时,开始显示键盘并接收到UIKeyboardWillShowNotifi
四.使用inputAccessoryView与inputView定制输入视图
inputAccessoryView和 inputView属性在 UIResponder中定义,为readonly的属性,但在UITextFiled和UITextView中重新定义为了readwrite的属性,可以由用户赋值。若 inputView的不为nil,则当文本视图成为first responder时,不会显示系统键盘,而是显示自定义的inputView;若inputAccessoryView不
为nil,则inputAccessoryView会显示在系统键盘或定制inputView的上方。当使用inputView时,仍然会有WillShow,DidShow,WillHide,DidHide的键盘通知,通知中的BeginFrame与EndFrame为系统键盘(或inputView)与inputAccessoryView一起的frame。
自定义inputAccessoryView非常常见,如编辑短信时的输入框
Web页面输入键盘
新浪微博评论界面
若想在输入时不使用系统键盘,而使用自定义的键盘,则可以设置inputView,如随手记中的金额输入时的键盘
若不想使用键盘输入,想从UIPickerView或UIDatePicker中选择,可设置inputView为对应的Picker视图,如图
苹果键盘示例程序 KeyboardAccessory演示了inputAccessoryView的使用方法。
iOS,Want a “button” above a UIPicker or Keyboard, inputView,inputAccessoryView演示了在UIPickerView之上添加Toolbar的代码。
在标准视图中只有UITextField和UITextView将inputView和inputAccessoryView重新定义为了readwrite类型,若想在自定义视图中使用,需要在自定义视图中重新定义inputView和inputAccessoryView属性。见Input Views and Input Accessory Views。
参考:
Text, Web, and Editing Programming Guide for iOS – Managing the Keyboard
Text,Web, and Editing Programming Guide for iOS – Input Views and Input Accessory Views
UITextView Class Reference
UITextField Class Reference
UIResponder Class Reference
UIWindow Class Reference
UITextInputTraits Protocol Reference
KeyboardAccessory Demo
Different way to show keyboard and resize UIView with text field
iOS, Want a “button” above a UIPicker or Keyboard, inputView, inputAccessoryView
UIKeyboardFrameBeginUser
UIKeyboard键盘相关知识点-IOS开发
Change UISearchBar/Keyboard Search Button Title
iOS Human Interface Guidelines Keyboards and Input Views
How change keyboard background color in iOS?
Favorites UI design