您的位置:首页 > 产品设计 > UI/UE

有关UITextField被键盘遮挡的代码

2013-11-21 17:09 337 查看
最近做项目开发,遇到了一个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了.

这是楼主的第一个正式项目,感觉学到了不少,纯小白作品,大牛无视之.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: