一句話設定當前控制器的view跟隨鍵盤起伏,媽媽再也不用擔心鍵盤擋住輸入框了

劇情的需要發表於2017-09-27

專案中有很多輸入框,有輸入框就會喚出鍵盤,喚出鍵盤就很經常鍵盤擋住輸入框。如何解決這個問題?

這個問題並不難,相信大家都會寫。但是寫多了大家就會發現,專案中這麼多頁面有輸入框的,那就意味著很多地方都要寫,而且寫的程式碼都差不多。那有沒有方便點的,全域性控制控制器的view跟隨鍵盤起伏,或者呼叫一句程式碼就可以搞定的?

針對這個問題,為此我實現了一句話設定當前控制器的view跟隨鍵盤起伏。

程式碼不多隻有輕量級的兩個類:

螢幕快照 2017-09-15 下午7.02.33.png
螢幕快照 2017-09-15 下午7.02.33.png

看看效果:

Untitled2.gif
Untitled2.gif

實現思路 主要程式碼實現:

1、監聽輸入框開始編輯,鍵盤改變的通知

// TextField開始編輯
        [[NSNotificationCenter defaultCenter] addObserver:instance selector:@selector(textFieldTextDidBeginEditingNotification:) name:UITextFieldTextDidBeginEditingNotification
                                                   object:nil];
        // TextView開始編輯
        [[NSNotificationCenter defaultCenter] addObserver:instance selector:@selector(textViewTextDidBeginEditingNotification:) name:UITextViewTextDidBeginEditingNotification
                                                   object:nil];
        // 鍵盤將要改變
        [[NSNotificationCenter defaultCenter] addObserver:instance selector:@selector(keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];複製程式碼

2、獲取當前的控制器,判斷鍵盤是否擋住輸入框,然後計算偏移view

/// 偏移View
-(void)transformView:(NSNotification *)notification {
    //獲取鍵盤彈出後的Rect
    NSValue *keyBoardEndBounds=[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect  endRect=[keyBoardEndBounds CGRectValue];

    UIView *targetView;
    if ([self.inputObject isKindOfClass:[UIView class]]) {
        targetView = self.inputObject;
    }
    if (!targetView) {
        return;
    }

    UIViewController *vc = [self getCurrentVC];

    // targetView 在 toView 的 convertRect位置上的位置
    CGRect targetRect = [targetView convertRect:CGRectMake(0, 0, targetView.frame.size.width, targetView.frame.size.height) toView:vc.view];
    CGFloat height = [UIScreen mainScreen].bounds.size.height;
    CGFloat maxY = CGRectGetMaxY(targetRect);
    CGFloat cha = endRect.origin.y - maxY;

    if (maxY > endRect.origin.y) { // 鍵盤會擋住輸入框

        if ([vc.view.subviews.firstObject isKindOfClass:[UIScrollView class]]) {// 如果self.view是UIScrollView,則滾動contentOffset
            UIScrollView *scrollView= vc.view.subviews.firstObject;
            //NSLog(@"%@",NSStringFromCGPoint(scrollView.contentOffset));
            scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y + (-cha) + 10);
        }else {
            CGFloat interval = 0;
            if (cha < -10) {
                interval = 10;
            }
            [UIView animateWithDuration:0.25f animations:^{
                [vc.view setFrame:CGRectMake(vc.view.frame.origin.x, cha - interval, vc.view.frame.size.width, vc.view.frame.size.height)];
            }];
        }
    }
    if (endRect.origin.y == height) { //鍵盤迴收 deltaY>100
        //NSLog(@"鍵盤迴收");
        if ([vc.view.subviews.firstObject isKindOfClass:[UIScrollView class]]) {
            //UIScrollView *scrollView= self.view.subviews.firstObject;
            //NSLog(@"%@",NSStringFromCGPoint(scrollView.contentOffset));
        }else {
            [UIView animateWithDuration:0.25f animations:^{
                [vc.view setFrame:CGRectMake(0, 0, vc.view.frame.size.width, vc.view.frame.size.height)];
            }];
            self.inputObject = nil;
            self.keyboardNotifivation = nil;
        }
    }
}複製程式碼

使用方式有兩種:

第一種:只匯入JHKeyBoardManager.h這個類到專案中,在AppDelegate寫一句程式碼即可

#import "JHKeyBoardManager.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [JHKeyBoardManager sharedManager];
    return YES;
}複製程式碼

第二種:只匯入UIViewController+KeyBoardManager.h這個類到專案中,要用的控制器只需掉用一個方法即可

#import "UIViewController+KeyBoardManager.h"
- (void)viewDidLoad {
    [super viewDidLoad];
    [self transformViewForKeyboard];
}複製程式碼

demo地址:github.com/iOSHJH/JHKe…

有問題歡迎issues,若專案對你有用還望不吝給個star讓我動力十足?

相關文章