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> ...
随机推荐
- Spring Cloud Eureka 自我保护机制实战分析
前些天栈长在Java技术栈微信公众号分享过 Spring Cloud Eureka 的系列文章: Spring Cloud Eureka 自我保护机制 Spring Cloud Eureka 常用配置 ...
- mysql 设置默认id自增开始下标
alter table 表名 AUTO_INCREMENT 此处写你想让id从几开始增长的数字:
- PyTorch学习笔记之nn的简单实例
method 1 import torch from torch.autograd import Variable N, D_in, H, D_out = 64, 1000, 100, 10 x = ...
- python为不同的对象如何分配内存的小知识
id方法的返回值就是对象的内存地址. python中会为每个出现的对象分配内存,哪怕他们的值完全相等(注意是相等不是相同).如执行a=2.0,b=2.0这两个语句时会先后为2.0这个Float类型对象 ...
- Nutch学习笔记二——抓取过程简析
在上篇学习笔记中http://www.cnblogs.com/huligong1234/p/3464371.html 主要记录Nutch安装及简单运行的过程. 笔记中 通过配置抓取地址http://b ...
- 南阳 oj 表达式求值 题目35 数据结构 NYO题目链接
建议不会的看别人的代码自己在之上模拟一遍,仅仅要耐心模拟就会做出来 题目链接:http://acm.nyist.net/JudgeOnline/problem.php? pid=35 #incl ...
- 配置Office Outlook 2013
导航 背景——配置过程——错误(Error)——参考资料 背景 最近,折腾了一阵子邮箱客户端,包括:Foxmail.thuderbird.outlook:最后,考虑到outlook对文本的强大的支持能 ...
- jquery easyui 全部图标
所有的图标在 jquery-easyui-1.2.6\themes\icons 目录下, 在icon.css定义的如何引用 jquery-easyui-1.2.6/themes/icon.css .i ...
- VueJS表达式支持:逻辑控制或运算
HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...
- sql time 比较
数据字段为varchar类型的,格式:20110228 151010想进行时间比较,搜索一个范围内的时间select * from table where ' 20120102' <`time ...