標籤:
http://www.cocoachina.com/ios/20150703/12365.html
在涉及到表單輸入的介面中,我們通常需要監聽一些鍵盤事件,並根據實際需要來執行相應的操作。如,鍵盤彈起時,要讓我們的UIScrollView自動收縮,以能看到整個UIScrollView的內容。為此,在UIWindow.h中定義了如下6個通知常量,來配合鍵盤在不同時間點的事件處理:
| 123456 |
UIKeyboardWillShowNotification // 鍵盤顯示之前UIKeyboardDidShowNotification // 鍵盤顯示完成後UIKeyboardWillHideNotification // 鍵盤隱藏之前UIKeyboardDidHideNotification // 鍵盤訊息之後UIKeyboardWillChangeFrameNotification // 鍵盤大小改變之前UIKeyboardDidChangeFrameNotification // 鍵盤大小改變之後 |
這幾個通知的object對象都是nil。而userInfo字典都包含了一些鍵盤的資訊,主要是鍵盤的位置大小資訊,我們可以通過使用以下的key來擷取字典中對應的值:
| 12345678 |
// 鍵盤在動畫開始前的framelet UIKeyboardFrameBeginUserInfoKey: String// 鍵盤在動畫線束後的framelet UIKeyboardFrameEndUserInfoKey: String// 鍵盤的動畫曲線let UIKeyboardAnimationCurveUserInfoKey: String// 鍵盤的動畫時間let UIKeyboardAnimationDurationUserInfoKey: String |
在此,我感興趣的是鍵盤事件的調用順序和如何擷取鍵盤的大小,以適當的調整視圖的大小。
從定義的鍵盤通知的類型可以看到,實際上我們關注的是三個階段的鍵盤的事件:顯示、隱藏、大小改變。在此我們設定兩個UITextField,它們的鍵盤類型不同:一個是普通鍵盤,一個是數字鍵台。我們監聽所有的鍵盤事件,並列印相關日誌(在此就不貼代碼了),直接看結果。
1) 當我們讓textField1擷取輸入焦點時,列印的日誌如下:
| 1234 |
keyboard will changekeyboard will showkeyboard did changekeyboard did show |
2) 在不隱藏鍵盤的情況下,讓textField2擷取焦點,列印的日誌如下:
| 1234 |
keyboard will changekeyboard will showkeyboard did changekeyboard did show |
3) 再收合鍵盤,列印的日誌如下:
| 1234 |
keyboard will changekeyboard will hidekeyboard did changekeyboard did hide |
從上面的日誌可以看出,不管是鍵盤的顯示還是隱藏,都會發送大小改變的通知,而且是在show和hide的對應事件之前。而在大小不同的鍵盤之間切換時,除了發送change事件外,還會發送show事件(不發送hide事件)。
另外還有兩點需要注意的是:
-
如果是在兩個大小相同的鍵盤之間切換,則不會發送任何訊息
-
如果是普通鍵盤中類似於中英文鍵盤的切換,只要大小改變了,都會發送一組或多組與上面2)相同流程的訊息
瞭解了事件的調用順序,我們就可以根據自己的需要來決定在哪個訊息處理方法中來執行操作。為此,我們需要擷取一些有用的資訊。這些資訊是封裝在通知的userInfo中,通過上面常量key來擷取相關的值。通常我們關心的是UIKeyboardFrameEndUserInfoKey,來擷取動畫完成後,鍵盤的frame,以此來計算我們的scroll view的高度。另外,我們可能希望scroll view高度的變化也是通過動畫來過渡的,此時UIKeyboardAnimationCurveUserInfoKey和UIKeyboardAnimationDurationUserInfoKey就有用了。
我們可以通過以下方式來擷取這些值:
| 123456789 |
if let dict = notification.userInfo { var animationDuration: NSTimeInterval = 0 var animationCurve: UIViewAnimationCurve = .EaseInOut var keyboardEndFrame: CGRect = CGRectZero dict[UIKeyboardAnimationCurveUserInfoKey]?.getValue(&animationCurve) dict[UIKeyboardAnimationDurationUserInfoKey]?.getValue(&animationDuration) dict[UIKeyboardFrameEndUserInfoKey]?.getValue(&keyboardEndFrame) ......} |
實際上,userInfo中還有另外三個值,只不過這幾個值從iOS 3.2開始就已經廢棄不用了。所以我們不用太關注。
最後說下表單。一個表單介面看著比較簡單,但互動和UI總是能想出各種方法來讓它變得複雜,而且其實裡面設計到的細節還是很多的。像我們金融類的App,通常都會涉及到大量的表單輸入,所以如何做好,還是需要花一番心思的。空閑時,打算總結一下,寫一篇文章。
參考
-
UIWindow Class Reference
鍵盤事件的調用順序及擷取鍵盤大小