背景:
第三方键盘如搜狗输入法,在调起时会收到三次键盘事件通知,如果输入框随键盘移动会有一个先上后下的动画,很不友好。网上查了很多方法,基本都是说只处理最后一次事件,代码如下:
CGRect begin = [[[note userInfo] objectForKey:@"UIKeyboardFrameBeginUserInfoKey"] CGRectValue];
CGRect end = [[[note userInfo] objectForKey:@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
//因为第三方键盘或者是在键盘加个toolbar会导致回调三次,这个判断用来判断是否是第三次回调,原生只有一次
if(begin.size.height>0 && (begin.origin.y-end.origin.y>0)){
//处理逻辑
}
但此方法有个缺陷,键盘高度变小时无法被执行,如最新的搜狗输入法有搜索表情的功能,点击展开正常,但是再次点击却无法收起。
解决方法:
UIKeyboardWillShowNotification事件只处理键盘从底部到出现的事件
UIKeyboardWillHideNotification事件处理键盘隐藏事件
keyboardWillChangeFrame事件处理键盘出现过程的高度变化事件
所以先注册这三个事件
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
定义一个宏 :
#define UIScreenHeight [[UIScreen mainScreen]bounds].size.height
定义一个成员变量:
@property (nonatomic,strong) NSMutableDictionary *keyboardChangeDic; //存储键盘高度变化值 和 时间戳
-(void)keyboardWillShow:(NSNotification*)notification
{
CGRect begin = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect end = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
if(!(end.size.height > 0 && begin.origin.y >= UIScreenHeight &&(begin.origin.y - end.origin.y > 0))){
//不执行
return;
}
//在此处处理键盘出现逻辑
}
-(void)keyboardWillChangeFrame:(NSNotification*)notification
{
//如果键盘展开时高度变化则执行
CGRect begin = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect end = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
if(begin.size.height == 0 || end.size.height == 0 || begin.origin.y >= UIScreenHeight || end.origin.y >= UIScreenHeight ){
return;
}
//以下代码是为了解决某些输入法键盘高度会先变小后马上变大的问题,表现为闪烁
CGFloat oldKeyboardH = [[self.keyboardChangeDic safeObjectForKey:@"keyboardH"] doubleValue];
CGFloat oldChangeH = [[self.keyboardChangeDic safeObjectForKey:@"changeH"] doubleValue];
NSTimeInterval oldTimeStamp = [[self.keyboardChangeDic safeObjectForKey:@"timeStamp"] doubleValue];
CGFloat changeH = ABS(begin.size.height - end.size.height);
NSTimeInterval timeStamp = [[NSDate date]timeIntervalSince1970];
[self.keyboardChangeDic setObject:@(changeH) forKey:@"changeH"];
[self.keyboardChangeDic setObject:@(timeStamp) forKey:@"timeStamp"];
[self.keyboardChangeDic setObject:@(begin.size.height) forKey:@"keyboardH"];
if (oldChangeH != 0 && oldChangeH == changeH && timeStamp - oldTimeStamp < 0.1) {
self.keyboardHeight = oldKeyboardH;
} else {
self.keyboardHeight = end.size.height;
}
WEAKSELF
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//根据self.keyboardHeight调整自己的输入框位置
});
}
虽然判断比较多,但是可以解决键盘闪烁和收到多次通知的问题,如果你有更好的方法请赐教~~
网友评论