监听键盘高度变换

//
//  JLKeyboardListener.h
//  Keyboard
//
//  Created by Jack on 2017/4/11.
//  Copyright © 2017年 buakaw. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol JLKeyboardListenerDelegate <NSObject>

@required
- (void)keyboardWillShowHeight:(CGFloat)height withDuration:(NSTimeInterval)duration;

- (void)keyboardWillHideHeight:(CGFloat)height withDuration:(NSTimeInterval)duration;

/**
 键盘高度发生改变

 @param height 新的键盘高度
 @param heightOffset 发生改变偏移量,大于0表示高度增加
 @param duration 动画持续时间
 */
- (void)keyboardWillChangeHeight:(CGFloat)height offset:(CGFloat)heightOffset withDuration:(NSTimeInterval)duration;

@end

@interface JLKeyboardListener : NSObject

@property (nonatomic,weak) id<JLKeyboardListenerDelegate> delegate;

@property (nonatomic,assign,readonly) CGFloat currentKeyboardHeight;

- (void)startListen;

- (void)stopListen;

@end

//
//  JLKeyboardListener.m
//  Keyboard
//
//  Created by Jack on 2017/4/11.
//  Copyright © 2017年 buakaw. All rights reserved.
//

#import "JLKeyboardListener.h"

@interface JLKeyboardListener ()

@property (nonatomic,assign) CGFloat keyboardHeight;
@property (nonatomic,assign) NSTimeInterval keyboardAnimationDuration;
@property (nonatomic,assign) BOOL showsKeyboard;

@end

@implementation JLKeyboardListener


- (instancetype)init {
    if (self = [super init]) {
        self.showsKeyboard = NO;
    }
    return self;
}

- (void)dealloc {
    [self stopListen];
}

- (void)startListen {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    // 键盘通知
    [notificationCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(keyboardChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

- (void)stopListen {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self];
}


#pragma mark - keyboard Notification

/**键盘隐藏*/
- (void)keyboardWillHide:(NSNotification *)notification {
    
    if (self.showsKeyboard) {
        self.showsKeyboard = NO;

        if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillHideHeight:withDuration:)]) {
            [self.delegate keyboardWillHideHeight:self.keyboardHeight withDuration:self.keyboardAnimationDuration];
        }
    }
}

/**键盘显示*/
- (void)keyboardWillShow:(NSNotification *)notification {
    
    NSTimeInterval duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    CGRect begin = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGRect end = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
    if (duration == 0) {
        duration = 0.25;
    }
    self.keyboardAnimationDuration = duration;
    if (!self.showsKeyboard) {
        // 第三方键盘三次回调,仅执行最后一次(仅以搜狗输入法作的测试)
        if (begin.size.height > 0 && begin.origin.y - end.origin.y > 0) {
            
            self.showsKeyboard = YES;
            self.keyboardHeight = end.size.height;
            if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillShowHeight:withDuration:)]) {
                [self.delegate keyboardWillShowHeight:self.keyboardHeight withDuration:self.keyboardAnimationDuration];
            }
            
        }
    }

    
}

/**在使用过程中切换键盘*/
- (void)keyboardChangeFrame:(NSNotification *)notification {
    
    CGRect begin = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGRect end = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
    // 在屏幕旋转时也会走这个方法,但是此时键盘会 hide -> show -> changeFrame
    if (self.showsKeyboard) {
        
        // 在ip6s中使用搜狗输入法和系统键盘切换时发现
        // sougou --> sys : 282 -> 258
        // sys --> sougou : 258 -> 0 -> 216 -> 282 也就是说系统键盘先下去隐藏,再弹出搜狗,在弹出搜狗的过程中在216处有回调
        
        CGFloat offset = end.size.height - begin.size.height;
        self.keyboardHeight = end.size.height;
        
        if (offset != 0) {
            NSTimeInterval changeFrameAnimationDuartion = 0.25;
            if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillChangeHeight:offset:withDuration:)]) {
                [self.delegate keyboardWillChangeHeight:self.keyboardHeight offset:offset withDuration:changeFrameAnimationDuartion];
            }
        }
    } else {
        
        // ios11 键盘通知改变。Show Keyboard调用
        if (end.origin.y < begin.origin.y) {
            self.showsKeyboard = YES;
            CGFloat offset = end.size.height - begin.size.height;
            self.keyboardHeight = end.size.height;
            if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillChangeHeight:offset:withDuration:)]) {
                [self.delegate keyboardWillChangeHeight:self.keyboardHeight offset:offset withDuration:self.keyboardAnimationDuration];
            }
        }
        
    }
    
    
}

#pragma mark - Getter

- (CGFloat)currentKeyboardHeight {
    return self.keyboardHeight;
}

@end

 

posted @ 2017-04-11 14:17  Emerys  阅读(380)  评论(0编辑  收藏  举报