处理键盘遮挡输入框的方法很多,不管怎么说,网上有个第三方还是很不错的.但是工程中第三方库还是越少越好.
这里通过给UITextField添加类别方法来实现
这里涉及到 键盘和输入框
比较简单的做法是监听键盘发出的通知.毕竟键盘的frame的改变可能会遮档到输入框.
很多做法是监听键盘出现和键盘隐藏的通知.
但是切换输入法可能也会使键盘frame发生改变.
所以我比较建议的是监听键盘frame发生的改变.
- 给分类添加需要的方法
-(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的变更了.