淺談鍵盤遮擋輸入框的處理<類別方法>

處理鍵盤遮擋輸入框的方法很多,不管怎么說,網上有個第三方還是很不錯的.但是工程中第三方庫還是越少越好.
這里通過給UITextField添加類別方法來實現
這里涉及到 鍵盤和輸入框
比較簡單的做法是監聽鍵盤發出的通知.畢竟鍵盤的frame的改變可能會遮檔到輸入框.
很多做法是監聽鍵盤出現和鍵盤隱藏的通知.
但是切換輸入法可能也會使鍵盤frame發生改變.
所以我比較建議的是監聽鍵盤frame發生的改變.

  1. 給分類添加需要的方法
    -(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的變更了.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容