iPhone OS文本系统的设计者考虑了移动设备用户的基本需求,将文本系统设计为电子邮件和SMS程序中常用的单行和多行文本输入控件。文本系统支持Unicode,且包含几个不同的输入法,方便显示和读取不同语言的文本。
关于文本和Web的支持
iPhone OS的文本系统提供了大量的功能,同时又非常简单易用。UIKit框架中包含几个高级类,负责管理文本的显示和输入。该框架还含有一个更为高级的类,用于显示HTML和基于JavaScript的内容。
本文的下面部分将描述iPhone OS对文本和web内容的基本支持。如果您需要这里列举的各个类的更多信息,请参见UIKit框架参考。
文本视图
UIKit框架提供三个显示文本内容的基本类:
UILabel
显示静态文本字符串
UITextField
显示单行可编辑文本
UITextView
显示多行可编辑文本
虽然标签和文本编辑框通常用于显示相对少量的文本,但实际上这些类可以显示任意数量的文本。然而,基于iPhone OS的设备的屏幕比较小,为了使显示在屏幕上的文本便于阅读,这些类不支持像Mac OS X这样的桌面操作系统上常见的高级格式功能。另一方面,考虑到可能的需要,这三个类仍然支持指定字体信息,包括字体的尺寸和风格选项,只是指定的字体会应用到对象中显示的所有文本。
图5-1显示了这些文本类在屏幕上的显示实例。这些例子来自UICatalog示例程序,该程序演示了UIKit框架中的很多视图和控件。左图显示的是几个不同风格的文本输入框,右图则显示一个文本视图。灰色背景中显示的说明文字所在的视图是一些
UILabel
对象,它们被嵌入到负责显示各种视图的表格单元中。左图的屏幕底部还有一个
UILabel
对象,显示内容为 “Left View”。
图5-1 UICatalog应用程序的文本类
在使用可编辑的文本视图时,您必须提供一个委托对象,负责管理编辑会话。文本视图会向委托对象发送几个不同的通告,让它知道编辑何时开始,何时结束,并使它有机会重载某些编辑动作。举例来说,委托可以决定当前文本是否包含有效的值,还可以在需要的时候防止编辑会话被终止。在编辑过程最终结束的时候,您可以通过委托取得编辑结果,更新应用程序的数据模型。
由于各种文本视图的用法有轻微的不同,所以它们的委托方法也有所不同。为
UITextField
类提供支持的委托需要实现
UITextFieldDelegate
协议定义的方法。类似地,为
UITextView
类提供支持的委托需要实现
UITextViewDelegate
协议定义的方法。对于上述两种情形,系统并没有要求您一定要实现协议中的任何方法,但是如果没有实现必要的方法,文本输入框就没有什么用处了。有关这两个协议的更多信息,请参见UITextFieldDelegate协议参考和UITextViewDelegate协议参考。
Web视图
UIWebView
类使您可以将一个微型web浏览器集成到应用程序的用户界面上。
UIWebView
类充分使用了iPhone OS上的web技术,同样的这些技术也用于实现iPhone OS上的Safari、实现对HTML、CSS、和JavaScript内容的全面支持。
UIWebView
还支持很多用户在Safari中已经熟悉了的手势,比如通过双击和双指捏夹(pinch)的手势来放大和缩小页面,还有通过手指拖动来滚动页面。
除了显示内容,您还可以用web视图对象来显示web表单,收集用户输入。和UIKit的其它文本类相似,如果您在web页面的表单中有可编辑的文本框,则轻触该文本框就会弹出键盘,用户可以通过键盘输入文本。这是web浏览整体体验的一部分,web视图会自行管理键盘的显示和消除。
图5-2显示了一个
UIWebView
对象的例子,它来自UICatalog示例程序,该程序演示了UIKit框架中的很多视图和控件。这个例子只是显示HTML内容,如果您希望用户可以象使用web浏览器那样在网页之间进行漫游,需要加入一些控件。比如,图中的web视图只是占用URL文本框下面的空间,而不包含文本框的本身。
图5-2 web视图
web视图通过其关联的委托对象提供有关网页何时被装载、及装载过程是否发生错误的信息。web委托是指实现一个或多个
UIWebViewDelegate
协议方法的对象。您可以通过实现委托方法来响应装载错误或处理一些与装载有关的其它任务。更多有关
UIWebViewDelegate
协议方法的信息请参见UIWebViewDelegate协议参考。
键盘和输入法
每当用户触击一个可以接受文本输入的对象时,该对象就会请求系统显示一个合适的键盘。根据用户程序的需要和偏好的语言,系统可以显示几种不同的键盘。您的应用程序虽然不能控制用户的偏好语言(因此也不能控制键盘的输入法),但可以控制键盘的使用属性,比如特殊键的配置及其行为。
您可以直接通过应用程序中的文本对象来配置键盘的属性。
UITextField
和
UITextView
类都遵循
UITextInputTraits
协议,该协议定义了一些配置键盘的属性。在程序或Interface Builder的查看器窗口中设置这些属性就可以使系统显示指定类型的键盘。
请注意:虽然
UIWebView
类并不直接支持
UITextInputTraits
协议,但您还是可以配置文本输入元素的一些键盘属性。特别值得一提的是,您可以在输入元素的定义中包含
autocorrect
和
autocapitalization
属性,通过这些属性来指定键盘的行为,如下面的例子所示:
<input type="text" size="30" autocorrect="off" autocapitalization="on">
|
您不能在输入元素中指定键盘的类型。web视图显示的是缺省的键盘,但包含一些额外的控制,可以进行表单元素之间漫游。
缺省的键盘配置是为一般的文本输入设计的。图5-3显示了缺省的和其它的几个键盘配置。缺省键盘显示的是一个字母键盘,用户可以将它切换为数字和标点符号键盘。大多数其它键盘在都提供与缺省键盘类似的功能,同时又提供一些适合于特定任务的其它按键。但是,电话和数字键盘的布局显著不同,它们是特别为数字输入设计的。
图5-3 几个不同的键盘类型
为了实现不同的语言偏好,iPhone OS还支持与不同语言相对应的输入法和键盘布局, 图5-4显示了部分输入法和布局。输入法和键盘布局是由用户语言偏好设置决定的。
图5-4 几个不同的键盘和输入法
管理键盘
虽然很多UIKit对象在响应用户交互时会自动显示键盘,但您的程序仍然需要配置和管理键盘。本文的下面部分将描述应用程序在键盘管理方面应该承担的责任。
接收键盘通告
当键盘被显示或隐藏的时候,iPhone OS会向所有经过注册的观察者对象发出如下通告:
UIKeyboardWillShowNotification
UIKeyboardWillHideNotification
当键盘首次出现或者消失,以及键盘的所有者或应用程序的方向发生变化的任何时候,系统都会发出键盘通告。在上述的各种情况下,系统只发送与具体场景相关的的消息集合。举例来说,如果键盘的所有者发生变化,系统只向当前的拥有者发送
UIKeyboardWillHideNotification
消息,但不发送
UIKeyboardDidHideNotification
消息,因为这个变化不会导致键盘最终被隐藏。
UIKeyboardWillHideNotification
消息只是简单地通知键盘当前的所有者即将失去键盘焦点。而改变键盘的方向则会使系统发出上述的两种消息,因为每个方向的键盘是不同的,在显示新的键盘之前,必须先隐藏原来的键盘。
每个键盘通告都包含键盘在屏幕上的位置和尺寸。您应该使用通告中的信息来确定键盘的尺寸和位置,而不是假定键盘具有某个特定的尺寸或处于某个特定的位置。键盘在使用不同输入法时并一定总是一样的,在不同版本的iPhone OS上也可能会发生变化。另外,即使对于特定的某种语言和某个系统版本,键盘的尺寸也会因为应用程序方向的不同而不同。作为例子,请看图5-5显示了URL键盘在肖像模式和景观模式下的相对尺寸。使用键盘通告中的信息可以确保得到正确的尺寸和位置信息。
图5-5 在肖像模式和景观模式下的相对键盘尺寸
请注意: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:
方法将被触击的文本框滚动到视图中。
图5-6 调整内容的位置,使其适应键盘
请注意:在配置滚动视图时,请务必为所有的内容视图配置恰当的自动尺寸调整规则。在之前的图中,文本框实际上是一个
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
通告。您可以通过跟踪键盘是否确实被隐藏来避免多次减少滚动视图的尺寸。
程序清单5-2显示了一些额外的代码,视图控制器用这些代码来设置和清理之前例子中的
activeField
变量。在初始化时,界面中的每个文本框都将视图控制器设置为自己的委托。因此,当文本编辑框被激活的时候,这些方法就会被调用。更多关于文本框及其委托通告的信息,请参见UITextField类参考。
程序清单5-2 跟踪活动文本框的方法
- (void)textFieldDidBeginEditing:(UITextField *)textField
|
{
|
activeField = textField;
|
}
|
|
- (void)textFieldDidEndEditing:(UITextField *)textField
|
{
|
activeField = nil;
|
}
|
描画文本
除了显示和编辑文本的UIKit类之外,iPhone OS还包含几个直接在屏幕上描画文本的方法。描画简单字符串的最简单有效的方法是使用
NSString
类的UIKit扩展,该扩展包含一些在屏幕上描画字符串的方法,并且可以描画时使用多种属性。还有一些方法,可以在真正描画之前计算渲染字符串所需要的尺寸,这些方法有助于更加精确布局应用程序的内容。
重要提示:由于性能上的考虑,您应该尽可能避免直接描画文本。对于静态文本,通过一或多个
UILabel
对象进行描画比使用定制描画例程要高效得多。类似地,
UITextField
类也支持不同的风格,这些风格使您更加易于将可编辑的文本区域集成到您的内容中。
当您需要在界面上描画定制文本字符串时,请使用
NSString
方法。UIKit包含一些对基本
NSString
类的扩展,用于在视图中描画字符串。这些方法使您可以精确调整文本的位置,以及将文本和视图内容进行融合;这个类的方法还可以根据指定的字体和风格属性计算文本的包围矩形。更多信息请参见NSString UIKit扩展参考。
如果您需要对描画过程中用到的字体有更多的控制,还可以使用Core Graphics框架中的函数来进行描画。Core Graphics框架提供的方法可以对字形和文本进行精确描画和定位。有关这些函数及其用法的更多信息,请参见Quartz 2D编程指南和Core Graphics框架参考。
在Web视图中显示内容
如果您的用户界面包含
UIWebView
对象,就可以显示本地或网络上的内容。对于本地的内容,您可以动态创建,也可以使用文件,然后调用
loadData:MIMEType:textEncodingName:baseURL:
或
loadHTMLString:baseURL:
方法;如果要从网络加载,则需要创建一个
NSURLRequest
对象,然后传递给web视图对象的
loadRequest:
方法。
在发起一个基于网络的请求后,如果由于某种原因必须释放web视图,则必须在释放之前取消待处理的请求。为此,您可以调用web视图的
stopLoading
方法。通常情况下,您可以在web视图的视图控制器的
viewWillDisappear:
方法中执行这些代码。如果需要确定一个请求是否处于等待状态,可以通过web视图的
loading
属性来判断。