iOS隐藏键盘实现和针对键盘遮挡输入控件的解决

来源:互联网 发布:网络数据库和搜索引擎 编辑:程序博客网 时间:2024/06/11 21:03

iOS中,常见的输入控件主要有UITextField和UITextView。下面分别介绍针对这两种控件的实现。

新建一个项目,从设计器中拖入一个UITextField和一个UITextView,建立设计界面和代码连接后,将ViewController实现UITextField和UITextView的协议,并在viewDidLoad中设置控件的delete为self。

头文件如下

#import <UIKit/UIKit.h>@interface ViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate>@property (strong, nonatomic) IBOutlet UITextField *nameTextField;@property (strong, nonatomic) IBOutlet UITextView *introTextView;@end

viewDidLoad()中加入

nameTextField.delegate = self;introTextView.delegate = self;

下面完成具体实现。

1. 对于UITextField

UITextField只能输入一行,不支持多行输入,隐藏键盘的实现方式主要有2种。
  • 一是点击键盘的回车隐藏键盘
  • 二是点击界面的空白处隐藏键盘
上面两种方式的原理都是取消UITextField的第一响应者。

点击回车的实现如下
// 对于UITextField,点击回车关闭输入法- (BOOL)textFieldShouldReturn:(UITextField *)textField{    [textField resignFirstResponder];    return YES;}

点击界面空白处实现如下
// 对于UITextField和UITextView,点击空白界面关闭输入法- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    [nameTextField resignFirstResponder];    [introTextView resignFirstResponder];}
上面代码中,对于UITextView也是类似的实现。

下面看键盘遮挡输入控件的实现,
原理是当UITextField开始编辑时,将ViewController的位置上移以容下键盘,而编辑完成后将ViewController的位置恢复原处。这里只需要调整高度即可。

2. 动态获取键盘高度

注意,iOS5之前的键盘高度都是216.0f,iOS5之后,键盘的高度可以变化,因此需要动态获取。
获取的原理的是向ViewController发生通知UIKeyboardWillChangeFrameNotification,并在相应的事件处理中动态获取键盘高度。
为了能使键盘高度能在其他方法中使用,将键盘高度定义为私有成员变量
#import "ViewController.h"@interface ViewController (){    CGSize keyboardSize;    // 存放动态获取的键盘的大小}

在ViewDidLoad中添加通知,并为keyboardSize设置默认值
    // iOS5.0之后,键盘的高度不一定是216.0,需要动态获取,如今iOS版本几乎都是7.0+,因此此处不再判断iOS版本了    // 添加获取动态键盘大小的通知    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:     UIKeyboardWillChangeFrameNotification  object:nil];        // 设置keyboardSize默认值    keyboardSize.height = 216.0f;

记住,在视图卸载时,移除通知
- (void) viewDidUnload{    [[NSNotificationCenter defaultCenter] removeObserver:self];}


当键盘大小变化时获取的方法为
// 动态获取的键盘的大小- (void)keyboardWillShow:(NSNotification *)notification{NSDictionary *info = [notification userInfo];keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;}

获取到键盘的高度后,就可以完成开始编辑和结束编辑时的处理了
// 对于UITextField,开始编辑时,上移整个ViewController.view// <span style="font-size:24px;color:#ff0000;"><strong>有个问题是</strong></span>,对于UITextField,第一次出现时keyboardSize默认是0!因为textViewDidBeginEditing先于keyboardWillShow调用。而对于UITextView没有问题!// 解决办法,在viewDidLoad()中为keyboardSize设置默认值-(void)textFieldDidBeginEditing:(UITextField *)textField{    CGRect frame = textField.frame;    CGFloat offset = frame.origin.y + frame.size.height + 5 - (self.view.frame.size.height - keyboardSize.height);     // 这里的5可以调整输入框和输入法间距    NSTimeInterval animationDuration = 0.30f;   // 这里的0.30f可以调整动画时间    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];    [UIView setAnimationDuration:animationDuration];    if(offset > 0)    {        self.view.frame = CGRectMake(0.0f, -offset, self.view.frame.size.width, self.view.frame.size.height);    }    [UIView commitAnimations];}// 对于UITextField,编辑完成,恢复整个ViewController.view的位置-(void)textFieldDidEndEditing:(UITextField *)textField{    self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);}

3. 对于UITextView

对于UITextView,一般不会点击回车关闭键盘,关闭的方法主要有2种,
  • 一是点击界面空白处关闭键盘
  • 二是为键盘添加工具栏,在工具栏上添加按钮,完成键盘的关闭
第一种方法前面已经介绍了。
对于第二种,iOS为UITextField和UITextView添加了一个view属性
@property(readwrite, retain) UIView *inputAccessoryView
在viewDidLoad方法中设置这个view
    [introTextView setInputAccessoryView:toolbarView];
按住ALT查看该属性的介绍,如下

The custom accessory view to display when the text view becomes the first responder
The default value of this property is nil. Assigning a view to this property causes that view to be displayed above the standard system keyboard (or above the custom input view if one is provided) when the text view becomes the first responder. For example, you could use this property to attach a custom toolbar to the keyboard.

上面介绍的很清晰,设置一个新的工具栏view将放在输入法的最上面,从而完成一些其他操作

在viewDidLoad()中添加输入法工具栏的实现如下
    // 为UITextView的输入法界面添加一个工具栏,毕竟,对于UITextView,一般不会点击return关闭输入法的    UIToolbar * toolbarView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 30)];    [toolbarView setBarStyle:UIBarStyleDefault];    UIBarButtonItem * spaceBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];    UIBarButtonItem * closeBtn = [[UIBarButtonItem alloc]initWithTitle:@"关闭" style:UIBarButtonItemStyleDone target:self action:@selector(closeKeyBoard)];    NSArray * btnsArr = [NSArray arrayWithObjects:spaceBtn, closeBtn, nil];    [toolbarView setItems:btnsArr];    [introTextView setInputAccessoryView:toolbarView];
上面的spaceBtn是用于占位的,否则关闭按钮将跑到最左边。

关闭按钮实现
// 点击UITextView的输入法界面的关闭按钮,取消UITextView的第一响应者,关闭输入法界面- (void) closeKeyBoard{    [introTextView resignFirstResponder];}

效果如下


对于UITextView的遮挡输入控件实现和UITextField类似,如下
// 对于UITextView,开始编辑时,上移整个ViewController.view- (void) textViewDidBeginEditing:(UITextView *)textView{    CGRect frame = textView.frame;    CGFloat offset = frame.origin.y + frame.size.height + 5 - (self.view.frame.size.height - keyboardSize.height);     // 这里的5可以调整输入框和输入法间距    NSTimeInterval animationDuration = 0.30f;   // 这里的0.30f可以调整动画时间    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];    [UIView setAnimationDuration:animationDuration];    if(offset > 0)    {        self.view.frame = CGRectMake(0.0f, -offset, self.view.frame.size.width, self.view.frame.size.height);    }    [UIView commitAnimations];}// 对于UITextView,编辑完成,恢复整个ViewController.view的位置- (void) textViewDidEndEditing:(UITextView *)textView{    self.view.frame =CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);}

整个过程就是这样。可能还有一些问题,待以后解决。

Reference:
1. http://www.apkbus.com/blog-107838-44715.html
2. http://blog.csdn.net/enuola/article/details/7917221

上述代码地址:https://github.com/A1546488968/ios/tree/master/HideKeyboradAndSolveKeyboardHidesTextFieldAndTextViewTest

0 0