iOS 键盘遮挡输入框万能解决方案(多个输入框)
效果图如下:

思路分析:
当我们有很多输入框时,有时候键盘弹出来会遮挡着输入框。我们需要获取输入框和键盘相对于最外层视图的位置来判断是否遮挡,如果遮挡了计算出遮挡的高度,然后设置最外层视图的frame,往上移动到大于等于遮挡遮住的高度即可。当键盘隐藏是在讲最外层视图的frame还原回来。
代码:
Main.storyboard如下所示:

#import "ViewController.h"
@interface ViewController ()
@property(nonatomic ,strong) UITextField * firstResponderTextF;//记录将要编辑的输入框
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//监听键盘展示和隐藏的通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)dealloc{
//移除键盘通知监听者
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if ([self.firstResponderTextF isFirstResponder])[self.firstResponderTextF resignFirstResponder];
}
#pragma maek UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
self.firstResponderTextF = textField;//当将要开始编辑的时候,获取当前的textField
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
#pragma mark : UIKeyboardWillShowNotification/UIKeyboardWillHideNotification
- (void)keyboardWillShow:(NSNotification *)notification{
CGRect rect = [self.firstResponderTextF.superview convertRect:self.firstResponderTextF.frame toView:self.view];//获取相对于self.view的位置
NSDictionary *userInfo = [notification userInfo];
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];//获取弹出键盘的fame的value值
CGRect keyboardRect = [aValue CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:self.view.window];//获取键盘相对于self.view的frame ,传window和传nil是一样的
CGFloat keyboardTop = keyboardRect.origin.y;
NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//获取键盘弹出动画时间值
NSTimeInterval animationDuration = [animationDurationValue doubleValue];
if (keyboardTop < CGRectGetMaxY(rect)) {//如果键盘盖住了输入框
CGFloat gap = keyboardTop - CGRectGetMaxY(rect) - 10;//计算需要网上移动的偏移量(输入框底部离键盘顶部为10的间距)
__weak typeof(self)weakSelf = self;
[UIView animateWithDuration:animationDuration animations:^{
weakSelf.view.frame = CGRectMake(weakSelf.view.frame.origin.x, gap, weakSelf.view.frame.size.width, weakSelf.view.frame.size.height);
}];
}
}
- (void)keyboardWillHide:(NSNotification *)notification{
NSDictionary *userInfo = [notification userInfo];
NSNumber * animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];//获取键盘隐藏动画时间值
NSTimeInterval animationDuration = [animationDurationValue doubleValue];
if (self.view.frame.origin.y < 0) {//如果有偏移,当影藏键盘的时候就复原
__weak typeof(self)weakSelf = self;
[UIView animateWithDuration:animationDuration animations:^{
weakSelf.view.frame = CGRectMake(weakSelf.view.frame.origin.x, 0, weakSelf.view.frame.size.width, weakSelf.view.frame.size.height);
}];
}
}
@end
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
知识点:
1.当输入框将要编辑时会调- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField代理方法(本为用的都是UITextField),此时用一个全局变量firstResponderTextF来记录将要编辑的输入框。(好处就是如果很多输入框是局部变量一个个获取会比较麻烦,用一个全局变量来记录就会简单方便的多);
2. 键盘展示和隐藏的通知:UIKeyboardWillShowNotification,UIKeyboardWillHideNotification;可以获得键盘的frame和动画时长;通过计算键盘和输入框相对于最外层是视图的外置来判断是否被哲哲,如果遮住则间整体视图网上移动大于等于遮住的高度,当键盘隐藏的时候则还原来的位置;

对应的key:UIKeyboardFrameEndUserInfoKey键盘frame,UIKeyboardAnimationDurationUserInfoKey展示和影藏的动画时长;
3.相对于摸个视图位置的api(UIView):
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;//获取当前视图的点坐标相对于view上的点坐标
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;//获取view上的点坐标相对于当前视图的点坐标
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;//获取当前视图的frame相对于view上的frame
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;//获取view上的frame相对于当前视图的frame
- 1
- 2
- 3
- 4
问题:
如文中获取将要编辑的输入框相对于最外层视图的fameCGRect rect = [self.firstResponderTextF.superview convertRect:self.firstResponderTextF.frame toView:self.view];(这里其实应该算两次:要先获得输入框在父视图(红色或蓝色的view)中的位置来获得相对父视图的俯视图(黄色的view)的位置;然后才能获得输入框相对于最外层视图(白色的view),但文我直接用输入框在父视图(红色或蓝色的view)中的位置获得到了相对于最外层view(白色的view)的位置,并且结果正确,所以有些困惑,有理解的大神烦请指点一二);
原码:iOS 键盘遮挡输入框万能解决方案(多个输入框)
iOS 键盘遮挡输入框万能解决方案(多个输入框)的更多相关文章
- iOS键盘遮挡输入框,输入区域自动上移
在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹 ...
- H5 移动端 键盘遮挡焦点元素解决方案
前言 最近在做 webapp,遇到了很多移动端兼容的问题,其中一个问题就是:输入框触发 focus 后,键盘弹出,然后遮住了输入框. 然后在Android和IOS上,这个问题的表现形式不一样,而原生键 ...
- iOS键盘遮挡问题解决办法
iOS开发之“键盘遮挡输入框的解决办法”之一 -----键盘通知之前处理这种问题,总是在触发输入框编辑事件键盘弹出的时候,将当前的View整体向上移动,结束编辑又整体向下移,耗时耗力效率低. 在网上看 ...
- iOS 键盘遮挡输入 解决办法
.初始化及添加通知观察者 - (void)viewDidLoad { [super viewDidLoad]; self.tableView = [[UITableView alloc] initWi ...
- iOS学习——键盘弹出遮挡输入框问题解决方案
在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发 ...
- iOS解决表格中TextField,TextView编辑时,输入框被键盘遮挡的问题
方法1:在原来的 UIViewController 内部再添加一层 UITableViewController 代码如下 : // // ViewController.m // 键盘遮挡问题 // / ...
- 『零行代码』解决键盘遮挡问题(iOS)
关注仓库,及时获得更新:iOS-Source-Code-Analyze https://github.com/draveness/iOS-Source-Code-Analyze Follow: Dra ...
- Android软键盘遮挡的四种解决方案
问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...
- 移动端页面input输入框被键盘遮挡问题
<body class="layout-fixed"> <!-- fixed定位的头部 --> <header> </header> ...
随机推荐
- Java中没有C#的out关键字,但可以通过数组实现类似的效果
其实传递的就是数组的指针,里面的每一项的值还是那块内存,所以能直接操作里面的值.如果单纯传指定的值,那么里面操作的就是新的一块内存块. 用数组实现的效果如下: class B{ String cnt= ...
- 支持WEB、Android、IOS的地图解决方案
转自原文 支持WEB.Android.IOS的地图解决方案 工具链 GIS工具集 OpenGeo Suite 包含PostGIS, GeoServer, GeoWebCache, OpenLayers ...
- 【JVM】idea启动项目时候 添加jvm启动参数显示详细日志
-verbose:class
- 【GitHub】给GitHub上的ReadMe.md文件中添加图片怎么做 、 gitHub创建文件夹
1.首先在github上的仓库上,创建一个空的文件夹,用于上传图片 上图看 要点击的按钮是创建新的文件,并不是创建新的文件夹,具体怎么?往下看 这个时候,下面的提交按钮才能提交 2.进入新创建的文件夹 ...
- 如何模拟alert/confirm/prompt实现阻断程序运行
场景:在执行js的时候,我们希望运行到某处,进行用户交互,根据交互的内容,运行下面的程序:下面的js程序需要用的和用户交互的内容,所以,和用户交互时,后面的程序必须停止运行 方案: 1. 原生的ale ...
- 使用zerorpc踩的第一个坑:
Server端代码:注意s.run() 和 s.run的区别,一个括号搞死我了.如果不加括号,服务端服务是不会启动的,客户端就会报连接超时的错误 Server端在本机所有IP上监听4242端口的tcp ...
- Utuntu 和 window共享文件
由于自己想用服务器跑代码,数据集和模型一般都在本机电脑上,用实验室服务器需要拷贝数据或者,在服务器上重新下载数据很麻烦 都在局域网内可以实现文件共享,代码和数据都在本地,共享给服务器,只需要使用服务器 ...
- 微信公众平台SDK for node
实现了下面特性: 1.开启开发人员模式 2.解析微信请求參数 3.验证消息来源 4.被动回复文字消息 5.被动回复图文消息 6.获取access_token 7.创建自己定义菜单 地址:wechat ...
- 数据库如何让自增id重置
sql语句:truncate tablename; 会清空表的所有记录,并且使自增的id重置. 另外,navicat的截断表,就是这个功能. 它的清空表只会清空数据,不能使自增的id重置.
- 安装protobuf可能遇到的问题
下载protobuf-2.3.0: http://protobuf.googlecode.com/files/protobuf-2.3.0.zip http://code.google.com/ ...