iOS自定義鍵盤彈出view的位置移動(三種方法)

當彈出鍵盤時,自定義鍵盤上方的view,有三種解決辦法:

一個就是利用UITextField或者UITextView的inputAccessoryView屬性。

另一種,就是監聽鍵盤彈出的notification來自己解決相關視圖的位置問題。

還有一種是覆蓋 TextFileld 的一些方法。

第一種解決方法相對比較簡單,第二種的方法中有一個難題就是當鍵盤的輸入方式,也就是中英文切換時,鍵盤的高度是會發生變化的。需要動態來調整相關視圖的位置。設定inputAccessoryView屬性UITextField或者UITextView有一個inputAccessoryView的屬性,其類型是UIView。使用中,可以自定義一個view,并將這個view傳遞給inputAccessoryView的屬性即可。這種實現方式相對簡單,可以滿足很多情況的需求了。下面給出一些示例代碼。

// 新建一個UITextField,位置及背景顏色隨意寫的。

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 10, 200, 20)];

textField.backgroundColor = [UIColor grayColor];[self.view addSubview:textField];? ??

// 自定義的view

UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 70)];

customView.backgroundColor = [UIColor lightGrayColor];

textField.inputAccessoryView = customView;? ??

// 往自定義view中添加各種UI控件(以UIButton為例)

UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 5, 60, 20)];

btn.backgroundColor = [UIColor greenColor];[btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];

[customView addSubview:btn];

上面代碼很簡單,一看就明白了。這里的鍵盤時通過UITextField的becomeFirstResponder后彈出的。而我在開發中就碰到了一種情況,就是需要通過點擊一個按鈕來彈出鍵盤,同時鍵盤上方的自定義視圖中需要包含一個UITextView。這時,這種情況就不適用了。

需要用到第二種方法。監聽鍵盤事件動態改變自定義view位置這種方法的思路就是首先自己寫一個view,然后監聽鍵盤的事件,得到鍵盤的位置后調整自己寫的view的位置,保證這個view的下邊界與鍵盤的上邊界相接。在自定義view中包含一個UITextField或者UITextView。通過代碼調用其becomeFirstResponder方法來彈出鍵盤。下面寫一些關鍵代碼,其中自定義的view名為_mainView,全局變量。

監聽鍵盤事件代碼:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeContentViewPosition:) name:UIKeyboardWillShowNotification object:nil];[[NSNotificationCenter defaultCenter] addObserver:self? selector:@selector(changeContentViewPosition:)? name:UIKeyboardWillHideNotification object:nil];

移除監聽

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotificatition object:nil];

事件處理函數

// 根據鍵盤狀態,調整_mainView的位置

- (void) changeContentViewPoint:(NSNotification *)notification{? ?

????NSDictionary *userInfo = [notification userInfo];? ?

?????NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];? ?

?????CGFloat keyBoardEndY = value.CGRectValue.origin.y;??

????// 得到鍵盤彈出后的鍵盤視圖所在y坐標?

????NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];?

????NSNumber *curve = [userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];?

????// 添加移動動畫,使視圖跟隨鍵盤移動?

????[UIView animateWithDuration:duration.doubleValue animations:^{

?????[UIView setAnimationBeginsFromCurrentState:YES];

?????[UIView setAnimationCurve:[curve intValue]];

?????_mainView.center = CGPointMake(_mainView.center.x, keyBoardEndY - STATUS_BAR_HEIGHT - ? ? ? ? ?_mainView.bounds.size.height/2.0); // keyBoardEndY的坐標包括了狀態欄的高度,要減去 }];

}

其中添加了一個動畫,使得過渡效果好一點。 mainView中即可添加自定義的UI控件。注意,這個mainView中控件要從最下面開始布局,因為上述代碼是以下方為準的。

一開始,我也選擇了第二種,可是當點擊的時候,會發生延遲現象,還有救是中英文的問題,后來查資料,找到了第三種解決辦法。覆蓋 UITextField 的方法UITextField 的方法有如下:

@interface UIView (UITextField)

- (BOOL)endEditing:(BOOL)force;? ? // use to make the view or any subview that is the first responder resign (optionally force)@end@protocol UITextFieldDelegate@optional

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;? // return NO to disallow editing.

- (void)textFieldDidBeginEditing:(UITextField *)textField;? ? // became first responder

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;? // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end

- (void)textFieldDidEndEditing:(UITextField *)textField;? // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;? // return NO to not change text

- (BOOL)textFieldShouldClear:(UITextField *)textField;? // called when clear button pressed. return NO to ignore (no notifications)

- (BOOL)textFieldShouldReturn:(UITextField *)textField;? // called when 'return' key pressed. return NO to ignore.

@end

UIKIT_EXTERN NSString *const UITextFieldTextDidBeginEditingNotification;

UIKIT_EXTERN NSString *const UITextFieldTextDidEndEditingNotification;

UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

以下是我寫的代碼

//textField 變成第一響應著,意味著點擊了 textField,然后改變textFieldView 的位置坐標

- (void)textFieldDidBeginEditing:(UITextField *)textField? {

CGRect rect = self.textFieldView.frame;

rect.origin.y = self.view.frame.size.height - 216 - 10;

NSTimeInterval animationDuration = 0.3f;

[UIView beginAnimations:@"ResizeForKeyboard" context:nil];

[UIView setAnimationDuration:animationDuration];

self.textFieldView.frame = rect; [UIView commitAnimations];

}

//點擊虛擬鍵盤上的 return 按鈕后

- (BOOL)textFieldShouldReturn:(UITextField *)textField{

[self.textField resignFirstResponder];

return YES;

}

//對textFieldView 的位置調整,并返回 YES,從來返回

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{

CGRect rect = self.textFieldView.frame;

self.textFieldView.frame = CGRectMake(0, self.view.frame.size.height - 49 + 10, rect.size.width, rect.size.height);

return YES;

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容