监听键盘高度变换
// // 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