TextKit框架详细解析 (九) —— 文本编程指南之管理键盘(五)

版本记录

版本号 时间
V1.0 2018.09.01

前言

TextKit框架是对Core Text的封装,用简洁的调用方式实现了大部分Core Text的功能。 TextKit是一个偏上层的开发框架,在iOS7以上可用,使用它可以方便灵活处理复杂的文本布局,满足开发中对文本布局的各种复杂需求。TextKit实际上是基于CoreText的一个上层框架,其是面向对象的。接下来几篇我们就一起看一下这个框架。感兴趣的看下面几篇文章。
1. TextKit框架详细解析 (一) —— 基本概览和应用场景(一)
2. TextKit框架详细解析 (二) —— 基本概览和应用场景(二)
3. TextKit框架详细解析 (三) —— 一个简单布局示例(一)
4. TextKit框架详细解析 (四) —— 一个简单布局示例(二)
5. TextKit框架详细解析 (五) —— 文本编程指南之简介(一)
6. TextKit框架详细解析 (六) —— 文本编程指南之展示文本内容(二)
7. TextKit框架详细解析 (七) —— 文本编程指南之排版概念(三)
8. TextKit框架详细解析 (八) —— 文本编程指南之管理Text Fields and Text Views(四)

Managing the Keyboard - 管理键盘

当用户触摸text fieldtext viewweb view中的区域时,系统将显示键盘。 您可以配置显示的键盘类型以及键盘的多个属性。 您还必须在编辑会话开始和结束时管理键盘。 因为键盘可以隐藏作为编辑焦点的视图部分,所以此管理可能包括调整用户界面以提高焦点区域,以便在键盘上方可见。


Keyboards and Input Methods - 键盘和输入法

每当用户点击能够接受文本输入的对象时,该对象要求系统显示适当的键盘。 根据程序的需要和用户的首选语言,系统可能会显示多个不同键盘中的一个。 虽然您的应用程序无法控制用户的首选语言(以及键盘的输入方法),但它可以控制键盘的属性以指示其预期用途,例如任何特殊键的配置及其行为。

1. Configuring the Keyboard for Text Objects - 配置文本对象的键盘

您可以直接通过应用程序的文本对象配置键盘的属性。 UITextFieldUITextView类都符合UITextInputTraits协议,该协议定义了配置键盘的属性。 以编程方式或在Interface Builder检查器窗口中设置这些属性会导致系统显示指定类型的键盘。

默认键盘配置专为一般文本输入而设计。 图4-1显示了默认键盘以及其他几种键盘配置。 默认键盘最初显示字母键盘,但用户可以切换它并显示数字和标点符号。 大多数其他键盘提供与默认键盘类似的功能,但提供了特别适合特定任务的附加按钮。 然而,手机和数字键盘提供了一种截然不同的布局,可以根据数字输入进行定制。

Figure 4-1 Several different keyboard types

为了实现不同用户的语言首选项,iOS还支持不同语言的不同输入法和键盘布局,其中一些如图4-2所示。 键盘的输入方法和布局由用户的语言首选项决定。 其中一些键盘的输入分为多个阶段。

Figure 4-2 Several different keyboards and input methods

2. Configuring the Keyboard for Web Views - 配置Web视图的键盘

您可以为文本输入元素配置一些键盘属性。 例如,您可以在input元素的定义中包含autocorrectautocapitalize属性,以指定键盘的行为,如以下示例所示。

<input type="text" size="30" autocorrect="off" autocapitalize="on">

您还可以控制当用户触摸网页中的text field时显示的键盘类型。 要显示电话键盘,电子邮件键盘或URL键盘,请分别对输入元素的type属性使用telemailurl关键字。 要显示数字键盘,请将pattern属性的值设置为“[0-9] *”“\ d *”

这些关键字和模式属性是HTML 5的一部分,可在iOS中使用。 以下列表显示了如何显示每种类型的键盘,包括标准键盘。

  • 文字:<input type =“text”> </ input>
  • 电话:<input type =“tel”> </ input>
  • URL:<input type =“url”> </ input>
  • 电子邮件:<input type =“email”> </ input>
  • 邮编:<input type =“text”pattern =“[0-9] *”> </ input>

Managing the Keyboard - 管理键盘

虽然许多UIKit对象会自动显示键盘以响应用户交互,但您的应用仍然需要负责配置和管理键盘。 以下部分描述了这些职责。

1. Receiving Keyboard Notifications - 接收键盘通知

当键盘显示或隐藏时,iOS会向任何已注册的观察者发出以下通知:

每个键盘通知都包含有关键盘在屏幕上的大小和位置的信息。您可以使用UIKeyboardFrameBeginUserInfoKeyUIKeyboardFrameEndUserInfoKey键从每个通知的userInfo字典中访问此信息。

您应该始终使用这些通知中的信息,而不是假设键盘是特定大小或在特定位置。从一种输入法到另一种输入法,键盘的大小不保证是相同的,也可能在iOS的不同版本之间发生变化。此外,即使是单一语言和系统版本,键盘尺寸也可能因应用的方向而异。例如,图4-3显示了纵向和横向模式下URL键盘的相对大小。使用键盘通知内的信息可确保始终拥有正确的大小和位置信息。

Figure 4-3 Relative keyboard sizes in portrait and landscape modes

注意:userInfo字典的UIKeyboardFrameBeginUserInfoKeyUIKeyboardFrameEndUserInfoKey属性中包含的矩形只能用于它包含的大小信息。 不要在矩形交叉操作中使用矩形的原点(总是{0.0,0.0})。 由于键盘被动画到位,因此键盘的实际边界矩形会随着时间而变化。

使用键盘通知的一个原因是,您可以重新定位键盘在可见时隐藏的内容。 有关如何处理此方案的信息,请参阅Moving Content That Is Located Under the Keyboard

键盘通知的时间与视图控制器转换的时间之间没有确定的关系。

2. Displaying the Keyboard - 展示键盘

当用户点击视图时,系统会自动将该视图指定为第一响应者。当包含可编辑文本的视图发生这种情况时,视图会启动该文本的编辑会话。在该编辑会话开始时,视图要求系统显示键盘(如果键盘尚未显示)。如果键盘已经可见,则第一响应者的更改会导致键盘输入的文本被重定向到新点击的视图。

由于当视图成为第一响应者时键盘会自动显示,因此您通常无需执行任何操作来显示它。但是,您可以通过调用该视图的becomeFirstResponder方法以编程方式显示可编辑文本视图的键盘。调用此方法会使目标视图成为第一个响应者,并开始编辑过程,就像用户点击了视图一样。

如果您的应用在单个屏幕上管理多个基于文本的视图,最好跟踪哪个视图当前是第一个响应者,以便您以后可以关闭键盘。

3. Dismissing the Keyboard - 移除键盘

虽然它通常会自动显示键盘,但系统不会自动关闭键盘。相反,应用程序有责任在适当的时候关闭键盘。通常,您可以执行此操作以响应用户操作。例如,当用户点击键盘上的“返回”或“完成”按钮或点击应用界面中的其他按钮时,您可能会关闭键盘。根据您配置键盘的方式,您可能需要向用户界面添加一些额外的控件,以方便键盘被移除。

要关闭键盘,请调用当前第一个响应者的基于文本的视图的resignFirstResponder方法。当文本视图取消其第一个响应者状态时,它将结束其当前编辑会话,通知其代理该事实,并移除键盘。换句话说,如果你有一个名为myTextField的变量指向当前第一个响应者的UITextField对象,则解雇键盘就像执行以下操作一样简单:

[myTextField resignFirstResponder];

从那一点开始的所有内容都由文本对象自动处理。

4. Moving Content That Is Located Under the Keyboard - 移动位于键盘下的内容

当系统要求您显示键盘时,系统会将其从屏幕底部滑入,并将其放在应用内容上。因为它位于您的内容之上,所以键盘可以放在用户想要编辑的文本对象的顶部。发生这种情况时,您必须调整内容,以使目标对象保持可见。

调整内容通常涉及暂时调整一个或多个视图的大小并对其进行定位,以使文本对象保持可见。使用键盘管理文本对象的最简单方法是将它们嵌入UIScrollView对象或其子类之一,如UITableView。请注意,当有文本字段的内联编辑时,UITableViewController会自动调整其table view的大小并重新定位(要了解更多信息,请参阅View Controllers and Navigation-Based Apps)。

显示键盘时,您所要做的就是重置滚动视图的内容区域并将所需的文本对象滚动到位。因此,响应UIKeyboardDidShowNotification,您的处理程序方法将执行以下操作:

  • 1)获得键盘的大小。
  • 2)通过键盘高度调整滚动视图的底部内容插入。
  • 3)将目标text field滚动到视图中。

注意:由于键盘的高度在转换到屏幕时可能会发生变化,因此应始终使用UIKeyboardFrameEndUserInfoKey来帮助您避免键盘遮挡内容。

图4-4说明了在UIScrollView对象中嵌入多个text fields的简单应用程序的前面步骤。当键盘出现时,通知处理程序方法调整滚动视图的内容和滚动指示符插入,然后使用UIScrollViewscrollRectToVisible:animated:方法将点击的text field(在本例中为电子邮件字段)滚动到视图中。

Figure 4-4 Adjusting content to accommodate the keyboard

Listing 4-1显示了用于注册接收键盘通知的代码,并显示了这些通知的处理程序方法。此代码由管理滚动视图的视图控制器实现,而scrollView变量是指向滚动视图对象的outlet。 keyboardWasShown:方法从通知的信息字典中获取键盘大小,并通过键盘的高度调整滚动视图的底部内容插入。它还将滚动视图的scrollIndicatorInsets属性设置为相同的值,以便键盘不会隐藏滚动指示器。请注意,keyboardWillBeHidden:方法不使用键盘大小;它只是将滚动视图的contentInsetscrollIndicatorInsets属性设置为默认值UIEdgeInsetsZero

如果键盘隐藏了活动text field,则keyboardWasShown:方法会相应地调整滚动视图的内容偏移量。活动field存储在自定义变量(在此示例中称为activeField)中,该变量是视图控制器的成员变量,并在textFieldDidBeginEditing:代理方法中设置,该方法如Listing 4-2所示。 (在此示例中,视图控制器还充当每个text fields的代理。)

// Listing 4-1  Handling the keyboard notifications

// 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(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];
 
}
 
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] 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 app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}
 
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

Listing 4-2显示了视图控制器用于设置和清除前面示例中的activeField变量的一些附加代码。 在初始化期间,界面中的每个text field都将视图控制器设置为其代理。 因此,当text field变为活动状态时,它会调用这些方法。 有关text fields及其代理通知的详细信息,请参阅Managing Text Fields and Text Views

// Listing 4-2  Additional methods for tracking the active text field.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    activeField = textField;
}
 
- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeField = nil;
}

还有其他方法可以在模糊键盘上方的滚动视图中滚动编辑区域。 您可以使用键盘的高度扩展内容视图的高度,然后将已编辑的文本对象滚动到视图中,而不是更改滚动视图的底部内容插入。 尽管UIScrollView类具有可以为此目的设置的contentSize属性,但您也可以调整内容视图的frame,如Listing 4-3所示。 此代码还使用setContentOffset:animated:方法将已编辑的field滚动到视图中,在这种情况下,将其滚动到键盘顶部的上方。

// Listing 4-3  Adjusting the frame of the content view and scrolling a field above the keyboard

- (void)keyboardWasShown:(NSNotification*)aNotification {
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = activeField.superview.frame;
    bkgndRect.size.height += kbSize.height;
    [activeField.superview setFrame:bkgndRect];
    [scrollView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}

后记

本篇主要讲述了管理键盘,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容