有朋友问了一些关于iPhone键盘的问题, 那么总结一下, 在 iOS 程序中当想要在文本框中输入数据,点击文本框会打开键盘。对于 iPad 程序,其键盘有一个按钮可以用来关闭键盘,但是 iPhone 程序中的键盘却没有这样的按钮,不过我们可以采取一些方法关闭它。例如,我们可以实现按下 Return [Keyboard Type为defult] (有时也是 Done、Research 等)关闭键盘,或更人性化的,轻触背景关闭键盘。

1、首先讲一下按下Return键关闭键盘。

当按下键盘的 Return 键,会产生一个 Did End On Exit 事件,此时我们告诉文本框要放弃控件,于是键盘就消失了。在这个基础上,实现轻触 Return 关闭键盘,步骤为:

(1)在 ViewController.h 中声明一个方法:

- (IBAction)textFiledReturnEditing:(id)sender;
(2)在 ViewController.m 中实现这个方法:
- (IBAction)textFiledReturnEditing:(id)sender
{
[sender resignFirstResponder];
}
Snip20160511_2.png
Snip20160511_1.png

所谓 First Responder 译为第一响应者,指的就是用户当前正在与之交互的控件,。当用户使用键盘时,First Responder 就是这个键盘,resignFirstResponder 方法,顾名思义,就是放弃 First Responder 。

2、下面介绍更人性化的方法,轻触背景关闭键盘。

跟上面的步骤差不多,首先定义一个方法,然后实现这个方法,接下来将指定的控件映射到这个方法,并选择好所触发的事件。不同的是,这次我们要选择的控件不是上边的文本框,而是视图 View 本身。

(1)在 ViewController.h 文件中添加方法声明代码:
- (IBAction)backgroundTap:(id)sender;
(2)在ViewController.m中实现这个方法:
- (IBAction)backgroundTap:(id)sender
{
[self.textField resignFirstResponder];
}

需要说明的是,[self.textField resignFirstResponder]表示,如果textField有FirstResponder的话就放弃它,我们不用先判断firstField是否有,这条语句完全正确。

(3)让 View 映射到这个方法,不过事先,我们先要改变 View 的类型。

打开xib,选中 View ,打开 Identity Inspector ,在 class 中选择 UIControl :

Snip20160511_3.png

(4)在 Connector Inspector 中找到 Touch Down ,从它右边的圆圈中拉出映射线,映射到 ViewController.h 的 backgroundTap 方法,如下图:

Snip20160511_4.png

如此, 打开键盘之后,在空白区域点击一下,键盘就会向下收起来。

在论坛上也有只写一个backgroundTap 函数,然后将组件的事件和屏幕的事件指向同一个函数。其实这两个方法都是可以用的,但是呢,我更加倾向于使用同一个函数的方法,原因就要牵扯到第二个方面的知识:

解决虚拟键盘挡住UITextField的方法因为屏幕太小的缘故,一个键盘跳出来总是把输入框挡住,所以需要移动屏幕来匹配键盘.

3 解决虚拟键盘挡住UITextField的方法

- (void)keyboardWillShow:(NSNotification *)noti
{
//键盘输入的界面调整
//键盘的高度
float height = 216.0;
CGRect frame = self.view.frame;
frame.size = CGSizeMake(frame.size.width,frame.size.height - height);
[UIView beginAnimations:@"Curl"context:nil];
//动画开始
[UIView setAnimationDuration:0.30];
[UIView setAnimationDelegate:self];
[self.view setFrame:frame];
[UIView commitAnimations];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSTimeInterval animationDuration = 0.30f;
[UIView beginAnimations:@"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
CGRect rect = CGRectMake(0.0f, 0.0f, self.view.frame.size.width,self.view.frame.size.height);
//CGRect rect = CGRectMake(0.0f, 20.0f, self.view.frame.size.width, self.view.frame.size.height);
self.view.frame = rect;
[UIView commitAnimations];
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect frame = textField.frame;
//键盘高度216
int offset = frame.origin.y + 32 - (self.view.frame.size.height - 216.0);
NSTimeInterval animationDuration = 0.30f;
[UIView beginAnimations:@"ResizeForKeyBoard" context:nil];
[UIView setAnimationDuration:animationDuration];
float width = self.view.frame.size.width;
float height = self.view.frame.size.height;
if (offset > 0) {
CGRect rect = CGRectMake(0.0f, -offset,width,height);
self.view.frame = rect;
}
[UIView commitAnimations];
}
只要在代码中加入这三个文件,然后设置自身delegate就可以实现屏幕的移动,但是这里经常会有屏幕移动后不能返回的问题,这里的解决方案就是
- (IBAction)backgroundTap:(id)sender
{
NSTimeInterval animationDuration = 0.30f;
[UIView beginAnimations:@"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
CGRect rect = CGRectMake(0.0f, 0.0f, self.view.frame.size.width,self.view.frame.size.height);
self.view.frame = rect;
}

在backgroundTap函数中添加这些代码,这样屏幕就会返回正常了。