處理鍵盤遮擋輸入框的方法很多,不管怎么說,網上有個第三方還是很不錯的.但是工程中第三方庫還是越少越好.
這里通過給UITextField添加類別方法來實現
這里涉及到 鍵盤和輸入框
比較簡單的做法是監聽鍵盤發出的通知.畢竟鍵盤的frame的改變可能會遮檔到輸入框.
很多做法是監聽鍵盤出現和鍵盤隱藏的通知.
但是切換輸入法可能也會使鍵盤frame發生改變.
所以我比較建議的是監聽鍵盤frame發生的改變.
- 給分類添加需要的方法
-(void)setAutojust:(BOOL)autojust;
使用時直接設置就好了.
在實現文件中,定義一個keywindow的初始frame
#define OrignalRect [UIApplication sharedApplication].keyWindow.bounds
實現添加的方法
-(void)setAutojust:(BOOL)autojust{
if (autojust) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
}else{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
}
實現監聽的方法
-(void)keyboardWillChange:(NSNotification *)notice{
if (!self.isFirstResponder) {
return;
}
if (notice.name == UIKeyboardWillChangeFrameNotification ) {
//1.獲取改變的結束位置:
NSValue *endRectValue = [notice.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
CGRect endRect = endRectValue.CGRectValue;
//2.獲取動畫執行時間
NSNumber *duration = [notice.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];
CGFloat durationTime = duration.floatValue;
//3.判斷結束時 有沒有擋道輸入框
//轉換到同一坐標系
CGRect reletive = [self convertRect:self.bounds toView:[UIApplication sharedApplication].keyWindow];
CGFloat textMaxY = CGRectGetMaxY(reletive);
CGFloat keybordMinY = CGRectGetMinY(endRect);
//鍵盤彈起如果擋到了 改變window的frame
if (textMaxY >= keybordMinY) {
[UIView animateWithDuration:durationTime delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
CGRect windowRect = OrignalRect;
CGFloat space = 5;
windowRect.origin.y = keybordMinY -textMaxY - space;
[UIApplication sharedApplication].keyWindow.frame = windowRect;
} completion:nil];
return;
}
//4.如果鍵盤收回時 window 沒恢復 進行恢復
if (!CGRectEqualToRect([UIApplication sharedApplication].keyWindow.frame, OrignalRect)) {
[UIView animateWithDuration:durationTime delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[UIApplication sharedApplication].keyWindow.frame = OrignalRect;
} completion:nil];
}
}
}
當有多個輸入框的時候,直接切換到比較高的輸入框,再切換到其他地方,收起接盤,可能會出現windowframe沒回去的情況,因此這個時候,還需要監聽一下收起鍵盤的方法.因為雖然已經監聽了鍵盤改變的方法,但那個方法中判斷了是不是第一響應,而被擋到的可能早就不是第一響應了,因此那里面的方法不一定會走.
所以要單獨監聽 這里只用還原window的frame就可以
因此在設置監聽的方法中增加下列代碼
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
實現方法
-(void)keyboardWillHide:(NSNotification *)notice{
if (!CGRectEqualToRect([UIApplication sharedApplication].keyWindow.frame, OrignalRect)) {
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[UIApplication sharedApplication].keyWindow.frame = OrignalRect;
} completion:nil];
}
}
注意移除監聽者
- (void)dealloc
{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
這樣就可以了,如果想要更加完美的表現,要么使用第三方庫,要么需要在ViewCtr或者父視圖做未處理,因為分類方法只能獲得自己的相關屬性和狀態,如果一堆輸入框,處理起來比較麻煩.
目前這個分類方法,已經基本適應多個輸入框自適應鍵盤frame的變更了.