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閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容