iOS学习——键盘弹出遮挡输入框问题解决方案
在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码、查询时要输入查询信息、注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发过程中,一般用于进行输入信息的有两类:UITextField和UITextView,前者是单行输入文本框,后者是可滑动的多行输入文本框,在这整个开发过程中,我们需要控制键盘的弹出和收起、在输入结束的时候获取输入的信息,此外,我们还需要保证在键盘弹起的时候不遮挡我们输入的文本框。今天,我们就主要来说一下文本框输入的完整响应过程以及最后这个遮挡问题的解决方案。
一 文本框输入完整的响应过程
首先,我们要对UITextField和UITextView的输入输出进行控制,需要借助其对应的代理协议UITextFieldDelegate或UITextViewDelegate中的一些方法,两者在控制文本框中的相应流程稍有差别,但是都差不多,接下来,我们就从官方文档中开学习一下文本框输入完整的响应过程。在UITextFieldDelegate的官方文档中解释道:我们可以通过代理中的一些方法实现UITextField对键盘的调用,从而实现和用户进行交互的方法,此外,还可控制UITextField的输入过程。UITextField的整个输入过程分为如下7个步骤(如下过程,textfield换成textView即是TextView的响应过程):
- 在成为第一响应者之前,文本框调用其代理的 textFieldShouldBeginEditing: 方法来允许或阻止其第一响应者,并控制是否对文本框进行输入
- 成为第一响应者,对应的相应事件就是系统调用键盘(自动弹出),并且系统会根据需要发出
UIKeyboardWillShowNotification和UIKeyboardDidShowNotification的Notification通知,而如果此时系统中有其他的输入视图是可视的,则系统会发出UIKeyboardWillChangeFrameNotification和UIKeyboardDidChangeFrameNotification的通知 - 系统调用代理的 textFieldDidBeginEditing: 方法,并且发出
UITextFieldTextDidBeginEditingNotification的通知,此时光标已经在text field中定位了,键盘也已经弹出来了,接下来可以进行输入了 - 在输入信息过程中,当前文本内容改变就会调用 textField:shouldChangeCharactersInRange:replacementString: 方法,并且会发出
UITextFieldTextDidChangeNotification的通知。此外,当用户点击【clear/清除】按键时调用 textFieldShouldClear: 方法清除内容,当用户点击【return/完成】按键时调用 textFieldShouldReturn: 方法,注意:UITextViewDelegate没有对应清除和完成方法,所以我们不能调用 textFieldShouldClear: 方法和 textFieldShouldReturn: 方法实现【clear/清除】和【return/完成】按键的效果 - 在文本框输入即将结束,即即将注销第一响应者时,系统会调用 textFieldShouldEndEditing: 方法
- 文本框注销第一响应者,对应的响应时间就是系统收回键盘,并且在隐藏键盘时会发出
UIKeyboardWillHideNotification和UIKeyboardDidHideNotification的通知 - 最后,系统调用 textFieldDidEndEditing: 方法结束输入,并发出
UITextFieldTextDidEndEditingNotification的通知。
二 键盘的弹出与收起
2.1 弹出键盘的控制
关于键盘的弹出与收起问题,从上面的响应过程分析可知,键盘的弹出对于UITextField和UITextView都是自动弹出的,所以我们无需进行控制。如果需要进行控制,我们知道其实在弹出之前是调用了UITextFieldDelegate或UITextViewDelegate的以下方法来控制是否使当前文本框设置为第一响应者( becoming the first responder),文本框成为第一响应者的结果就是可以输入文本内容并弹出键盘,所以,我们可以在这个方法中通过返回值来判断是否弹出键盘。
//UITextField调用此方法
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//返回YES是弹出键盘 返回NO则不弹出键盘
} //UITextView调用此方法
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
//返回YES是弹出键盘 返回NO则不弹出键盘
}
2.1 收起键盘的控制
通过前面的分析我们知道,收起键盘主要是要注销文本框的第一响应者身份即可,所以,我们再需要控制键盘收起的时候调用 textFieldShouldEndEditing: 方法即可达到目的。关于收起键盘,我们通常有两种做法如下:
- 一是通过我们的键盘上的【return/完成】按键的点击事件来设置
- 二是设置点击空白处就收起键盘,这种方法现在比较普遍
这两种做法在UITextField和UITextView上的实现在我之前的随笔中有专门讲到过了,想了解的小伙伴可以直接戳这里:ios学习——键盘的收起
三 文本框内容的获取
在之前的分析中,我们知道,文本框在结束之后都会调用一个方法就是 textFieldDidEndEditing: / textViewDidEndEditing: 方法,这个方法就是方便我们在输入结束之后对文本框内容进行处理。如果我们开发过程中一个页面有多个相同类型的输入文本框,我们可以通过设置不同的tag来区分当前的是哪一个输入文本框,从而进行不同的处理,具体示例如下:
- (void)textViewDidEndEditing:(YYTextView *)textView{
if (textView.tag == ) {
NSString *reason = textView.text;
[self.submitInfoDic setObject:reason forKey:@"reason"];
} else {
NSString *remark = textView.text;
[self.submitInfoDic setObject:remark forKey:@"remark"];
}
}
四 键盘弹出的遮挡问题
还是在之前的分析中,我们知道在键盘弹出和收起时,系统都会发出对应的通知,所以我们可以在收到键盘弹出的时候判断键盘的位置和当前输入文本框的位置,如果有遮挡,就将当前视图进行一个向上平移,在收到键盘回收的通知时就平移到原先的位置。所以,主要分为2步:
- 注册键盘弹出和收起的通知事件
#pragma mark notification 通知管理
/**
* @brief 通知注册
* @return
*/
- (void)registNotification
{
// observe keyboard hide and show notifications to resize the text view appropriately
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
} - 实现收到键盘弹出和收起通知事件的响应事件
#pragma mark --键盘弹出收起管理
-(void)keyboardWillShow:(NSNotification *)note{
CGRect frame = self.textViewFrame;
//获取键盘高度
NSDictionary* info = [note userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
//140是文本框的高度,如果你的文本框高度不一样,则可以进行不同的调整
CGFloat offSet = frame.origin.y + - (self.view.frame.size.height - kbSize.height);
//将试图的Y坐标向上移动offset个单位,以使界面腾出开的地方用于软键盘的显示
if (offSet > 0.01) {
WEAKSELF
[UIView animateWithDuration:0.1 animations:^{
weakSelf.tableView.contentOffset = CGPointMake(, offSet);
}];
}
} -(void)keyboardWillHide:(NSNotification *)note{
[UIView animateWithDuration:0.1 animations:^{
self.tableView.contentOffset = CGPointMake(, );
}];
}
很多时候,我们有多个输入文本框,在我们的示例中,我们就有两个输入文本框,这时候我们收到通知的时候怎么判断是哪个文本框呢?在前的分析中,我们知道,在发出通知之前,系统会调用输入文本框代理的 textFieldShouldBeginEditing: 方法来判断是否允许编辑,那么我们可以在这个方法中判断是哪一个文本框以及文本框的具体位置等等,然后在键盘弹出时通过为止比较确定是否平移,以及平移的offset。
- (BOOL)textViewShouldBeginEditing:(YYTextView *)textView{
//获取当前输入文本框相对于当前view的位置
self.textViewFrame = [textView convertRect:textView.frame toView:self.view];
return YES;
}
iOS学习——键盘弹出遮挡输入框问题解决方案的更多相关文章
- iOS 键盘弹出遮挡输入框
#pragma mark 键盘弹出遮挡输入框 //开始编辑输入框的时候,软键盘出现,执行此事件 -(void)textFieldDidBeginEditing:(UITextField *)textF ...
- iOS学习——tableview中带编辑功能的cell键盘弹出遮挡和收起问题解决
最近在项目中经常用到UITableView中的cell中带有UITextField或UITextView的情况,然后在这种场景下,当我们点击屏幕较下方的cell进行编辑时,这时候键盘弹出来会出现遮挡待 ...
- 解决react-native软键盘弹出挡住输入框的问题
解决react-native软键盘弹出挡住输入框的问题 写登录页面,整体界面居中之后就出现软键盘弹出挡住输入框,用户体验不好的情况.用了RN官方的KeyboardAvoidingView组件,会有多出 ...
- H5页面IOS中键盘弹出导致点击错位的问题
IOS在点击输入框弹出键盘 键盘回缩 后 定位没有相应改变 还有 textarea 也会弹出键盘 $("input").blur(function() { console.l ...
- iOS 模拟器键盘弹出以及中文输入
1.虚拟键盘的弹出与收起切换: 快捷键:command+shift+K 2.中文输入: Xcode 菜单项 --> Product --> Scheme --> Edit Schem ...
- 处理安卓和ios当页面原生键盘弹出,输入框不显示
$('input').on('click', function () { var target = this; // 使用定时器是为了让输入框上滑时更加自然 setTimeout(function() ...
- 微信公众号系列 --- ionic在IOS的键盘弹出问题
在使用ionic开发IOS系统微信的时候会有一个苦恼的问题,填写表单的时候键盘会挡住输入框,其实并不算什么大问题,只要用户输入一个字就可以立刻看见输入框了. 可惜的是,有些客户是不讲理的,他才不管这个 ...
- ios 软键盘弹出布局被顶上去 已解决
document.body.addEventListener('focusout', () => { //软键盘收起的事件处理 set ...
- Android软键盘弹出,覆盖h5页面输入框问题
之前我们在使用vue进行 h5 表单录入的过程中,遇到了Android软键盘弹出,覆盖 h5页面 输入框 问题,在此进行回顾并分享给大家: 系统:Android 条件:当输入框在可视区底部或者偏下的位 ...
随机推荐
- Java企业微信开发_11_异常:java.net.UnknownHostException: qyapi.weixin.qq.com
原因: 网络原因导致 dns解析失败. 解决方案: 方案一 : 1.查看你的服务器能否ping通外网,不过不行说明你的网络出了问题. (我的情况是客户的应用服务器只能内网访问,所以是网络出问题 ...
- Sql Server中的nvarchar(n)和varchar(n)
刚才有幸看了下 nvarchar(n)和varchar(n),感觉以前的认知有误. nvarchar(n):n指的是字符个数,范围是1-4000,存储的是可变长度的Unicode字符数据. 按字符存储 ...
- PHP中引入文件的四种方式及区别
文件加载语句:include,require,include_once,require_once include,require: require函数通常放在 PHP 程序的最前面,PHP 程序在执行 ...
- C#窗口传值(CSDN实例)
//非模式窗体 相较独立From qform=new Form(); qform.Show(); //模式窗体 子依赖父Form qform=new Form();qform.Show ...
- 关于 const 的一点小研究
在饱受 var 的折磨之后,ES6 终于推出了新的定义变量的方法:let 和 const 和 var 相比,let 和 const 有了自己的作用域,let 用于定义变量,而 const 用于定义常量 ...
- vue 全局插槽 全局插座
场景: slot 能够让父组件内容插入到子组件中,但是子孙组件不能够使用slot直接插入内容.在弹窗的时候,全屏弹窗需要直接在组件最上层显示,如果父组件级别不够,弹出就可能不是全屏的. 知识点: 1: ...
- LindDotNetCore~Mock对实际应用中的意义
回到目录 Mock在单元测试里的意义 Mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以 便测试的测试方法.一个闹钟根据时间来进行提醒服务,如果过了下午5点 ...
- Centos6.5 登录时,提示Module is unkown
前一段时间,因工作需要在物理机上装了一个Centos6.5,但是,用了一段时间,发现再登录时,无论如何也登不进去了,并且也不提示用户名或者密码错误.我一度以为是在profile以及.bashrc或者. ...
- unity3d 打包个人记录
证书问题Android:CreateCer.bat ztmyseabed 路径:tool/Build/Windows/Android下iOS:MacCer文件夹如何上传ipa:修改版本号version ...
- Python 浅析线程(threading模块)和进程(process)
线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 进程与线程 什么 ...