最近做项目开发,遇到了一个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了.
这是楼主的第一个正式项目,感觉学到了不少,纯小白作品,大牛无视之.