有关UITextField被键盘遮挡的代码

最近做项目开发,遇到了一个ios初学者都会遇到的问题,就是文本框被键盘遮盖了,而ios系统又不会自动给你换位置,这纠结我一段时间,先看一个百度出镜率比较高的方法

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    NSLog(@"did开始编辑");
    NSLog(@"kbHeight=%f",kbHeight);
    CGRect frame=textField.frame;
    //假设触摸点在键盘覆盖范围内,获取该点需要上移离开键盘覆盖的长度
    int offset=frame.origin.y+frame.size.height+32-(self.frame.size.height-kbHeight);
    NSLog(@"offset=%d",offset);
    if (offset>0) {
        self.frame=CGRectMake(0.0f, -offset, self.frame.size.width, self.frame.size.height);
    }
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    NSLog(@"did结束编辑");
    self.frame =CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}

方法比较简单,为文本框添加委托,获得焦点时计算文本框到键盘顶部的距离然后改变文本框的frame,将其上移.但是该方法有很大的局限性,就是将文本框的高度定死,这就导致在应用横屏时UI布局会出现问题,而且当一个界面有多个文本框,切每一个文本框需要指定不同行为时,delegate这种做法就显得捉襟见肘了

楼主现在做的一个小项目,一个界面有5-6个文本框,且需要支持横屏和竖屏切换,这样一来上述方法就明显不合适了,只能自己再琢磨.因为控件较多,用了UIScrollView控件,想一下常规思路就是添加键盘出现消息,在键盘出现时改变scrollView的contentOffSet,但实际操作过程中发现键盘出现时文本框为第一响应者,此时在与键盘消息绑定的方法中改变scrollview的contentOffSet会使文本框失去第一响应者资格,于是改变contentOffSet只能放弃,那就改变scrollView的frame吧

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotification object:nil];
//关于这里为什么要接受willShow消息而不是DidShow消息,因为设计到scrollVoew位置的变化,会转变FirstResponder,因此选择WillShow消息
- (void)keyboardWillShow:(NSNotification *)notification{
    NSDictionary * userInfo = [notification userInfo];
    CGSize kbSize=[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue].size;
    
    //获取键盘高度
    float keyboardHeight=0;
    if (kbSize.width<kbSize.height) {//无论横屏还是竖屏,键盘的高度始终小于宽度
        keyboardHeight=kbSize.width;
    }else{
        keyboardHeight=kbSize.height;
    }
    NSLog(@"键盘高度=%f",keyboardHeight);

    //获取第一响应者
    UITextField * _txtField;
    for (UIView * _view in scrollView.subviews) {
        if ([_view isFirstResponder] && [NSStringFromClass(_view.class) isEqualToString:@"UITextField"] ) {
            _txtField=(UITextField * )_view;
        }
    }
    NSLog(@"获取到的文本框信息%@",_txtField);
    
    CGRect rectInView=[scrollView convertRect:_txtField.frame toView:self];
    NSLog(@"在当前界面的坐标x=%f,y=%f,width=%f,height=%f,",rectInView.origin.x,rectInView.origin.y,rectInView.size.width,rectInView.size.height);
    
    float _viewHeight=self.frame.size.height;
    NSLog(@"当前view 的高度=%f",_viewHeight);
    float _moreHeight =_txtField.frame.origin.y+_txtField.frame.size.height-(_viewHeight-keyboardHeight);
    NSLog(@"需要上移的高度%f",_moreHeight);
    if (_moreHeight>0) {
        scrollView.frame=CGRectMake(0, -_moreHeight, scrollView.frame.size.width, scrollView.frame.size.height);
    }
}

-(void)keyboardWillHide:(NSNotification * )notification{
    scrollView.frame=CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
}

这里有必要说一下,关于获取键盘高度的代码,官方文档中提示可以用convertRect:fromWindow: 方法将键盘的坐标转换,但在实际操作过程中我发现无论应用为横屏还是竖屏状态,键盘的frame属性是以iphone竖屏时的屏幕左下角为原点的,这也导致了用convertRect:fromWindow: 方法转换到scrollView中的数据无法使用(可能楼主比较小白,没怎么看书,这也得实践才知道,求轻喷),但在实际操作中楼主发现无论横屏还是竖屏状态,ipone虚拟键盘的宽度是种比高度要大,于是动态获取键盘高度问题瞬间解决了,然后就是简单的计算frmae需要上移多少高度才能正好到达键盘上方了,当然你得先判断一下键盘出现以后是否会遮挡到文本框,如果没有遮盖就不用多此一举移动scrollView了.

这是楼主的第一个正式项目,感觉学到了不少,纯小白作品,大牛无视之.

原文地址:https://www.cnblogs.com/candr/p/3435941.html