標籤:blog http io ar os 使用 sp for strong
iOS5 切換中文鍵盤時覆蓋輸入框的完美解決方案
原文:http://wangsheng2008love.blog.163.com/blog/static/782016892012631102714562/
2012-07-31 22:42:43| 分類: iOS | 標籤:ios5 中文鍵盤 遮蓋 輸入框 |舉報|字型大小 訂閱
眾所周知,iOS5之前,iPhone上的鍵盤的高度是固定為216.0px高的,中文漢字的選擇框是懸浮的,所以不少應用都將此高度來標註鍵盤的高度(包括米聊也是這麼做的)。
可是在iOS5中,鍵盤配置變了,尤其是中文輸入時,中文漢字選擇框就固定在鍵盤上方,這樣就使得原本與鍵盤緊密貼合的介面視圖被中文漢字選擇框給覆蓋住了。一方面影響了介面的美觀,另一方面,如果被覆蓋的部分就是文本輸入框的話,使用者就無法看到輸入的內容了。因此這個問題就必須得解決了。
解決方案:
其實在一開始使用216.0px這個固定值來標註鍵盤的高度就是錯誤的。因為在iOS3.2以後的系統中,蘋果就提供了鍵盤使用的API以及Demo程式——“KeyboardAccessory”。
處理鍵盤事件的正確方法是這樣的:(包括擷取鍵盤的位置以及鍵盤彈出和消失動畫的時間)
1)在要使用鍵盤的視圖控制器中(既viewDidLoad中),接收鍵盤事件的通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
// 鍵盤高度變化通知,ios5.0新增的
#ifdef __IPHONE_5_0
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
#endif
2)然後添加鍵盤事件的處理代碼:
擷取到當前keyboard的高度以及動畫時間,然後對視圖進行對應的操作即可。
#pragma mark -
#pragma mark Responding to keyboard events
- (void)keyboardWillShow:(NSNotification *)notification {
/*
Reduce the size of the text view so that it‘s not obscured by the keyboard.
Animate the resize so that it‘s in sync with the appearance of the keyboard.
*/
NSDictionary *userInfo = [notification userInfo];
// Get the origin of the keyboard when it‘s displayed.
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Get the top of the keyboard as the y coordinate of its origin in self‘s view‘s coordinate system. The bottom of the text view‘s frame should align with the top of the keyboard‘s final position.
CGRect keyboardRect = [aValue CGRectValue];
// Get the duration of the animation.
NSValue *animationDurationValue = [userInfoobjectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];
// Animate the resize of the text view‘s frame in sync with the keyboard‘s appearance.
[UIView animateWithDuration:animationDuration animations:^{
//此處的viewFooter即是你的輸入框View
//20為狀態列的高度
self.viewFooter.frame = CGRectMake(viewFooter.frame.origin.x, keyboardRect.origin.y-20-viewFooter.frame.size.height,viewFooter.frame.size.width, viewFooter.frame.size.height);
} completion:^(BOOL finished){
}];
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary* userInfo = [notification userInfo];
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
/*
Restore the size of the text view (fill self‘s view).
Animate the resize so that it‘s in sync with the disappearance of the keyboard.
*/
[UIView animateWithDuration:0 animations:^{
self.viewFooter.frame = CGRectMake(viewFooter.frame.origin.x, keyboardRect.origin.y-20-viewFooter.frame.size.height,viewFooter.frame.size.width, viewFooter.frame.size.height);
} completion:^(BOOL finished){
}];
}
3)在視圖控制器消除時(即viewDidUnload中),移除鍵盤事件的通知:
[[NSNotificationCenter defaultCenter] removeObserver:self];
在一個多項輸入介面上,會有多個uitextfield類型的輸入框。為了滾動方面,我們會將他們一一添加到uitableview的cell中,從而組成一個可以上下滑動的資料輸入介面。
但是字元輸入是通過系統自動彈出軟鍵盤來完成的,因此在選擇螢幕底端的cell時,會被軟鍵盤的地區所覆蓋。
同樣,正因為輸入框是在uitableview的cell中,所以可以將所在的cell滾動到軟鍵盤覆蓋的地區之上的位置。使得我們能看到輸入框。
現在,我們要實現這個操作過程。
我們可以簡單的將該cell滾動到表視圖的可見地區的最上方的位置。
uitableview提供了這個方法“scrolltorowatindexpath:atscrollposition:animated:”。作為第一反應者的輸入框,可以它的委託方法- (void)textfielddidbeginediting:(uitextfield*)textfield
將其賦值一個變數lastedittextfield中。軟鍵盤的出現和消失都註冊到該視圖控制器類中,並實現它的方法。這樣,在uitextfield啟用彈出鍵盤時,系統會自動認可一個軟鍵盤彈出的通知。鍵盤彈出通知會調用一個方法。
該方法要實現的邏輯是根據lastedittextfield所在的位置點,得到操作的cell,再將此cell滾動到視圖可見地區的最上方。
cgpoint pt =lastedittextfield.center;
pt = [self.tableview convertpoint:ptfromview:lastedittextfield.superview];
nsindexpath* indexpath = [self.tableviewindexpathforrowatpoint:pt];
[self.tableview scrolltorowatindexpath:indexpathatscrollposition:uitableviewrowanimationtop animated:yes];
這段代碼中,最重要的是根據lastedittextfield.center的值,通過uiview的執行個體方法-(cgpoint)convertpoint:(cgpoint)point fromview:(uiview *)view 將它轉成self.tableview的座標體系下的值。再根據新座標體系中lastedittextfield.center的值,通過uitableview的執行個體方法scrolltorowatindexpath:atscrollposition:animated:將該cell滾動到螢幕最上方。
在鍵盤消失時,系統會再發送一個通知,將螢幕恢複到原來的位置。
將輸入框滾動到最上方,雖然能滿足我們的輸入可見要求。但是,如果能只滾動到軟鍵盤之上方,而不是uitableview的最上方;在輸入框不在鍵盤覆蓋的地區時,是不需要滾動的。這樣的處理,將是更滿意的結果。
iOS5 切換中文鍵盤時覆蓋輸入框的完美解決方案