参考:http://blog.sina.com.cn/s/blog_45e2b66c01015j4m.html
键盘和输入法
每当用户触击一个可以接受文本输入的对象时,该对象就会请求系统显示一个合适的键盘。根据用户程序的需要和偏好的语言,系统可以显示几种不同的键盘。您的应用程序虽然不能控制用户的偏好语言(因此也不能控制键盘的输入法),但可以控制键盘的使用属性,比如特殊键的配置及其行为。
您可以直接通过应用程序中的文本对象来配置键盘的属性。UITextField
和UITextView
类都遵循UITextInputTraits
协议,该协议定义了一些配置键盘的属性。在程序或Interface Builder的查看器窗口中设置这些属性就可以使系统显示指定类型的键盘。
请注意:虽然UIWebView
类并不直接支持UITextInputTraits
协议,但您还是可以配置文本输入元素的一些键盘属性。特别值得一提的是,您可以在输入元素的定义中包含autocorrect
和autocapitalization
属性,通过这些属性来指定键盘的行为,如下面的例子所示:
<input type="text" size="30" >
|
缺省的键盘配置是为一般的文本输入设计的。图5-3显示了缺省的和其它的几个键盘配置。缺省键盘显示的是一个字母键盘,用户可以将它切换为数字和标点符号键盘。大多数其它键盘在都提供与缺省键盘类似的功能,同时又提供一些适合于特定任务的其它按键。但是,电话和数字键盘的布局显著不同,它们是特别为数字输入设计的。
为了实现不同的语言偏好,iPhone OS还支持与不同语言相对应的输入法和键盘布局, 图5-4显示了部分输入法和布局。输入法和键盘布局是由用户语言偏好设置决定的。
管理键盘
虽然很多UIKit对象在响应用户交互时会自动显示键盘,但您的程序仍然需要配置和管理键盘。本文的下面部分将描述应用程序在键盘管理方面应该承担的责任。
接收键盘通告
当键盘被显示或隐藏的时候,iPhone OS会向所有经过注册的观察者对象发出如下通告:
当键盘首次出现或者消失,以及键盘的所有者或应用程序的方向发生变化的任何时候,系统都会发出键盘通告。在上述的各种情况下,系统只发送与具体场景相关的的消息集合。举例来说,如果键盘的所有者发生变化,系统只向当前的拥有者发送UIKeyboardWillHideNotification
消息,但不发送UIKeyboardDidHideNotification
消息,因为这个变化不会导致键盘最终被隐藏。UIKeyboardWillHideNotification
消息只是简单地通知键盘当前的所有者即将失去键盘焦点。而改变键盘的方向则会使系统发出上述的两种消息,因为每个方向的键盘是不同的,在显示新的键盘之前,必须先隐藏原来的键盘。
每个键盘通告都包含键盘在屏幕上的位置和尺寸。您应该使用通告中的信息来确定键盘的尺寸和位置,而不是假定键盘具有某个特定的尺寸或处于某个特定的位置。键盘在使用不同输入法时并一定总是一样的,在不同版本的iPhone OS上也可能会发生变化。另外,即使对于特定的某种语言和某个系统版本,键盘的尺寸也会因为应用程序方向的不同而不同。作为例子,请看图5-5显示了URL键盘在肖像模式和景观模式下的相对尺寸。使用键盘通告中的信息可以确保得到正确的尺寸和位置信息。
请注意:info字典中的UIKeyboardBoundsUserInfoKey
键包含的矩形只能用于取得尺寸信息,不要将该矩形的原点(它的值总是为{0.0, 0.0})用于矩形计算。由于键盘是以动画的形式出现在它的位置上的,其实际的边界尺寸会随着时间的不同而不同,因此,info字典中有UIKeyboardCenterBeginUserInfoKey
和UIKeyboardCenterEndUserInfoKey
两个键,用于保存键盘的起始和终止的位置,您可以根据这些位置计算出键盘的原点。
使用键盘通告的一个原因是为了重新定位被键盘遮掩的内容。有关如何进行重新定位的信息,请参见“移动键盘下面的内容”部分。
显示键盘
当用户触击一个视图时,系统就会自动将该视图作为第一响应者。而当这种场景发生在包含可编辑文本的视图时,该视图就会启动一个文本编辑会话。如果当前键盘不可见,该视图会在编辑会话刚开始时请求系统显示键盘。如果键盘已经显示在屏幕上了,第一响应者的改变会导致来自键盘的文本输入被重定向到用户刚刚触击的视图上。
键盘是在视图变为第一响应者时自动被显示的,因此,您通常不需要为了显示它而做什么工作。但是,您可以通过调用视图对象的becomeFirstResponder
方法来为可编辑的文本视图显示键盘。调用这个方法可以使目标视图成为第一响应者,并开始编辑过程,其效果和用户触击该视图是一样的。
如果您的应用程序在一个屏幕上管理几个基于文本的视图,则需要跟踪当前哪个视图是第一响应者,以便在需要的时候取消键盘的显示。
取消键盘
虽然键盘通常是自动显示的,但它并不自动取消。相反,您的应用程序需要在恰当的时机取消键盘。通常情况下,您在响应用户动作的时候进行这样的操作,比如当用户触击键盘上的Return或Done按键、或者触击应用程序界面上的其它按键时。根据键盘配置的不同,您可能需要在用户界面上加入额外的控件来取消键盘。
您可以调用作为当前第一响应者的文本视图的resignFirstResponder
方法来取消键盘。当文本视图失去第一响应者的状态时,就会结束其当前的编辑会话,将这个变化通知它的委托对象,并取消键盘。换句话说,如果您有一个名为myTextField
的变量,指向一个UITextField
对象,假定该对象是当前的第一响应者,则可以简单地通过下面的代码来取消键盘:
[myTextField resignFirstResponder];
|
从这个点之后的所有操作都由文本对象自动处理。
移动键盘下面的内容
当系统收到显示键盘的请求时,就从屏幕的底部滑出键盘,并将它放在应用程序内容的上方。由于键盘位于您的内容的上面,所以有可能遮掩住用户希望编辑的文本对象。如果这种情况发生,就必须对内容进行调整,使目标对象保持可见。
需要做的调整通常包括暂时调整一或多个视图的尺寸和位置,从而使文本对象可见。管理带有键盘的文本对象的最简单方法是将它们嵌入到一个UIScrollView
(或其子类,如UITableView
)对象。当键盘被显示出来时,您需要做的只是调整滚动视图的尺寸,并将目标文本对象滚动到合适的位置。为此,在UIKeyboardDidShowNotification
通告的处理代码中需要进行如下操作:
-
取得键盘的尺寸。
-
将滚动视图的高度减去键盘的高度。
-
将目标文本框滚动到视图中。
图5-6演示了一个简单的应用程序如何处理上述的几个步骤。该程序将几个文本输入框嵌入到UIScrollView
对象中,当键盘出现时,通告处理代码首先调整滚动视图的尺寸,然后用UIScrollView
类的scrollRectToVisible:animated:
方法将被触击的文本框滚动到视图中。
请注意:在配置滚动视图时,请务必为所有的内容视图配置恰当的自动尺寸调整规则。在之前的图中,文本框实际上是一个UIView
对象的子视图,该UIView对象又是UIScrollView
对象的子视图。如果该UIView对象的UIViewAutoresizingFlexibleWidth
和UIViewAutoresizingFlexibleHeight
选项被设置了,则改变滚动视图的边框尺寸会同时改变它的边框,因而可能导致不可预料的结果。禁用这些选项可以确保该视图保持尺寸不变,并正确滚动。
程序清单5-1显示了如何注册接收键盘通告和如何实现相应的处理器方法。这段代码是由负责滚动视图管理的视图控制器实现的,其中scrollView
变量是一个指向滚动视图对象的插座变量。每个处理器方法都从通告的info对象取得键盘的尺寸,并根据这个尺寸调整滚动视图的高度。此外,keyboardWasShown:
方法的任务是将当前活动的文本框矩形滚入视图,该文本框对象存储在一个定制变量中(在本例子中名为activeField
),该变量是视图控制器的一个成员变量,在textFieldDidBeginEditing:
委托方法中进行赋值,委托方法本身的代码显示在程序清单5-2中(在这个例子中,视图控制器同时也充当所有文本输入框的委托)。
程序清单5-1 处理键盘通告
// Call this method somewhere in your view controller setup code.
|
- (void)registerForKeyboardNotifications
|
{
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
selector:@selector(keyboardWasShown:)
|
name:UIKeyboardDidShowNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
selector:@selector(keyboardWasHidden:)
|
name:UIKeyboardDidHideNotification object:nil];
|
}
|
|
// Called when the UIKeyboardDidShowNotification is sent.
|
- (void)keyboardWasShown:(NSNotification*)aNotification
|
{
|
if (keyboardShown)
|
return;
|
|
NSDictionary* info = [aNotification userInfo];
|
|
// Get the size of the keyboard.
|
NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
|
CGSize keyboardSize = [aValue CGRectValue].size;
|
|
// Resize the scroll view (which is the root view of the window)
|
CGRect viewFrame = [scrollView frame];
|
viewFrame.size.height -= keyboardSize.height;
|
scrollView.frame = viewFrame;
|
|
// Scroll the active text field into view.
|
CGRect textFieldRect = [activeField frame];
|
[scrollView scrollRectToVisible:textFieldRect animated:YES];
|
|
keyboardShown = YES;
|
}
|
|
|
// Called when the UIKeyboardDidHideNotification is sent
|
- (void)keyboardWasHidden:(NSNotification*)aNotification
|
{
|
NSDictionary* info = [aNotification userInfo];
|
|
// Get the size of the keyboard.
|
NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
|
CGSize keyboardSize = [aValue CGRectValue].size;
|
|
// Reset the height of the scroll view to its original value
|
CGRect viewFrame = [scrollView frame];
|
viewFrame.size.height += keyboardSize.height;
|
scrollView.frame = viewFrame;
|
|
keyboardShown = NO;
|
}
|
上面程序清单中的keyboardShown
变量是一个布尔值,用于跟踪键盘是否可见。如果您的用户界面有多个文本输入框,则用户可能触击其中的任意一个进行编辑。发生这种情况时,虽然键盘并不消失,但是每次开始编辑新的文本框时,系统都会产生UIKeyboardDidShowNotification
通告。您可以通过跟踪键盘是否确实被隐藏来避免多次减少滚动视图的尺寸。