iOS避免键盘遮挡输入方案
项目中经常会遇到这样的问题:一个tableView中有大量的textField,当点击屏幕底部的textfield时,由于键盘弹出挡住了textfield输入框里的内容,造成很差的用户体验,如下图,点击价格那一行,会出现图二这种效果(弹出的键盘完全遮盖了输入)。
图一:
图二:
解决思路:自定义一个textfield,声明一个公用方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight: 并实现它,这个方法的作用是调整controller的view的y值使整个view上移,让被点击的textfield显示出来,建议在controller的view的textfield的代理方法 -(void)textFieldDidBeginEditing: 中获取自定义的textfield,并调用它的此方法(开始编辑时就调整view的y值)。
1.自定义textfield:
实现公用方法: - (void)adjustTextFieldFrameWhenBeginEdtingWithView:
- (void)adjustTextFieldFrameWhenBeginEdtingWithView:(UIView *)view keyBoardHeight:(CGFloat)keyboadHeight
{
// 将控制器view保存起来
self.adjustView = view; // 将textfield的坐标转换到控制器view坐标系中
CGRect selfFrame = [self convertRect:self.bounds toView:view]; // 键盘的y值
CGFloat keyBoardY = ; keyBoardY = [UIScreen mainScreen].bounds.size.height - keyboadHeight ; // 控制器view 要调整的高度
CGFloat adjustY = selfFrame.origin.y + selfFrame.size.height + MARGIN - keyBoardY; if (adjustY > ) { // 调整高度大于0 [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ view.y = - adjustY;
} completion:^(BOOL finished) { }];
}else{
[UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.y = ;
} completion:^(BOOL finished) { }];
} }
第13行用到了键盘的高度keyboadHeight,所以我们还需要在控制器中得到键盘的高度。
2.在控制器中获取键盘高度
在控制器的viewDidLoad方法中,注册通知(监听键盘出现的通知)。
//增加监听,当键盘出现或改变时收出消息
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
当键盘弹出时,获取键盘高度,并将键盘高度传入定义好的block
//当键盘出现或改变时调用
- (void)keyboardWillShow:(NSNotification *)aNotification
{
//获取键盘的高度
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
CGFloat keyboadHeight = keyboardRect.size.height; // 调用保存好的block并将键盘高度传入
self.editingBlock(keyboadHeight);
}
3.在控制器中调用textfield的自适应方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight:
在控制器的textdelegate方法 - (void)textFieldDidBeginEditing: 中,定义block,在block中调用自定义textfield的自适应方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight: ,并传入键盘高度。
之所以用block,是因为方法 - (void)textFieldDidBeginEditing: 被调用时,还没有获取到键盘高度,所以先将代码保存为block,等获取到键盘高度后再传入键盘高度,调用textfield的自适应键盘高度的方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight:
block中调用自定义textfield的 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight: 方法,并把键盘高度作为参数传入自定义textfield。
#pragma YDTextFieldDelegate - (void)textFieldDidBeginEditing:(UITextField *)textField
{
YDTextField *tf = (YDTextField *)textField; __weak typeof(self) weakSelf = self; // 定义block,等待keyboardWillShow:方法获取键盘高度后调用
self.editingBlock = ^(CGFloat keyboadHeight){ // 此处调用自定义textfield的自适应方法
[tf adjustTextFieldFrameWhenBeginEdtingWithView:weakSelf.view keyBoardHeight:keyboadHeight]; }; }
4. 输入完成后处理
在控制器viewDidLoad方法中,注册通知,监听键盘消失。
// 当键盘消失时响应
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
键盘消失后,将调整后的view还原。
// 当键盘消失时调用
- (void)keyboardWillHide:(NSNotification *)note
{
if ([note.name isEqualToString:UIKeyboardWillShowNotification]) { }else{
[UIView animateWithDuration:0.25 animations:^{
self.view.y = ;
} completion:^(BOOL finished) { }];
}
}
如此就完成了textfield的自适应,每次点击底部textfield,view会根据textfield的位置上移一段距离,不被键盘遮盖,效果如下:
图三:
图四:
附上demo代码:
控制器中代码:
//
// ViewController.m
// TextfieldDemo
//
// Created by heyode on 16/5/20.
// Copyright © 2016年 heyode. All rights reserved.
// #import "ViewController.h"
#import "YDTextField.h"
#import "UIView+frame.h"
// 键盘和当前活动textfield的间距
#define MARGIN 15 //定义随机色
#define randomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1]; typedef void(^textFieldDidBeginEditingBlock)(CGFloat keyboadHeight);
#define BASECOUNT 30 @interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate>
/** tableView */
@property (nonatomic,weak) UITableView *tableView; /** 数据源 */
@property (nonatomic,strong) NSMutableArray *datas; /** block */
@property (nonatomic,copy) textFieldDidBeginEditingBlock editingBlock; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; [self setUpDataSouce];
[self setUpTableView]; [self setUpNotification];
} - (void)setUpNotification
{
//增加监听,当键盘出现或改变时收出消息
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil]; // 当键盘消失时响应
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil]; } // 当键盘消失时调用
- (void)keyboardWillHide:(NSNotification *)note
{
if ([note.name isEqualToString:UIKeyboardWillShowNotification]) { }else{
[UIView animateWithDuration:0.25 animations:^{
self.view.y = ;
} completion:^(BOOL finished) { }];
}
} //当键盘出现或改变时调用
- (void)keyboardWillShow:(NSNotification *)aNotification
{
//获取键盘的高度
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
CGFloat keyboadHeight = keyboardRect.size.height; // 调用保存好的block并将键盘高度传入
self.editingBlock(keyboadHeight);
} - (void)setUpTableView
{
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView]; } - (void)setUpDataSouce
{
self.datas = [NSMutableArray array]; for (int i = ; i < ; i++) {
NSString *str = [NSString stringWithFormat:@"%i",i];
[self.datas addObject:str];
} } #pragma UITableviewDatasouce
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.datas.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle: reuseIdentifier:@"cell"];
} for (id view in cell.contentView.subviews) {
[(UIView *)view removeFromSuperview];
} cell.textLabel.text = self.datas[indexPath.row]; YDTextField *tf = [[YDTextField alloc] initWithFrame:CGRectMake(, (cell.height - cell.height - )/, cell.width , cell.height - )];
tf.tag = indexPath.row + BASECOUNT; tf.backgroundColor = randomColor;
tf.delegate = self; [cell.contentView addSubview:tf];
return cell;
} #pragma YDTextFieldDelegate - (void)textFieldDidBeginEditing:(UITextField *)textField
{
YDTextField *tf = (YDTextField *)textField; __weak typeof(self) weakSelf = self; // 定义block,等待keyboardWillShow:方法获取键盘高度后调用
self.editingBlock = ^(CGFloat keyboadHeight){ // 此处调用自定义textfield的自适应方法
[tf adjustTextFieldFrameWhenBeginEdtingWithView:weakSelf.view keyBoardHeight:keyboadHeight]; }; } @end
自定义textfield代码:
//
// YDTextField.m
// TextfieldDemo
//
// Created by heyode on 16/5/20.
// Copyright © 2016年 heyode. All rights reserved.
// #import "YDTextField.h"
#import "UIView+frame.h" // 键盘和当前活动textfield的间距
#define MARGIN 15 @interface YDTextField()
@property (weak, nonatomic) UIView *adjustView;
/**键盘高度 */
@property (nonatomic,assign) CGFloat keyboadHeight; @end @implementation YDTextField - (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self initialize]; }
return self;
} - (void)awakeFromNib
{ [self initialize];
} - (void)layoutSubviews
{
[super layoutSubviews];
} - (void)initialize
{ // 点击return时,结束编辑状态
[self addTarget:self action:@selector(endEditing:) forControlEvents:UIControlEventEditingDidEndOnExit];
} - (void)adjustTextFieldFrameWhenBeginEdtingWithView:(UIView *)view keyBoardHeight:(CGFloat)keyboadHeight
{
// 将控制器view保存起来
self.adjustView = view; // 将textfield的坐标转换到控制器view坐标系中
CGRect selfFrame = [self convertRect:self.bounds toView:view]; // 键盘的y值
CGFloat keyBoardY = ; keyBoardY = [UIScreen mainScreen].bounds.size.height - keyboadHeight ; // 控制器view 要调整的高度
CGFloat adjustY = selfFrame.origin.y + selfFrame.size.height + MARGIN - keyBoardY; if (adjustY > ) { // 调整高度大于0 [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ view.y = - adjustY;
} completion:^(BOOL finished) { }];
}else{
[UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.y = ;
} completion:^(BOOL finished) { }];
} } @end
iOS避免键盘遮挡输入方案的更多相关文章
- 《React-Native系列》44、基于多个TextInput的键盘遮挡处理方案优化
曾经写过两篇关于在ReactNative上处理键盘遮挡输入表单TextInput的情况.建议读者能够先看看 1.<React-Native系列>33. 键盘遮挡问题处理 2.<Rea ...
- iOS 处理键盘遮挡TextField、TextView问题
之前处理键盘遮挡问题都是在每一个控制器进行单独处理,这样做真的是非常的费事,今天在做项目的时候就想到自己封装一个,记录一下这个“跌宕起伏”的过程. 思路是这样的:计算文本编辑控件Frame与键盘Fra ...
- iOS 键盘遮挡输入 解决办法
.初始化及添加通知观察者 - (void)viewDidLoad { [super viewDidLoad]; self.tableView = [[UITableView alloc] initWi ...
- (iOS)关于键盘遮挡textfield问题
记录一下自己经常遇到问题.使用textfield(textview).当输入框位置比较靠下时,弹出的键盘会遮挡输入框,这是就需要动态移动输入框编辑状态时self.view的位置, 自己经常用的方法有两 ...
- ZYKeyboardUtil 全自动处理键盘遮挡事件
键盘遮盖输入控件或按钮在日常app开发中避之不及,考虑各种情况下UI各种嵌套,最后还要注册监听再获取指定键盘信息.我们可以通过键盘处理工具类ZYKeyboardUtil避繁就简,利用Block的方式处 ...
- iOS键盘遮挡输入框,输入区域自动上移
在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹 ...
- iOS开发笔记11:表单键盘遮挡、浮点数价格格式化显示、省市区选择器、View Debugging
1.表单键盘遮挡 应用场景为一个collectionView上有多个textfield.textView供用户填写信息. 之前输入项较少时,采取的方法比较粗暴,didSelectItemAtIndex ...
- iOS键盘遮挡问题解决办法
iOS开发之“键盘遮挡输入框的解决办法”之一 -----键盘通知之前处理这种问题,总是在触发输入框编辑事件键盘弹出的时候,将当前的View整体向上移动,结束编辑又整体向下移,耗时耗力效率低. 在网上看 ...
- iOS学习——键盘弹出遮挡输入框问题解决方案
在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发 ...
随机推荐
- 安装VMware vCenter过程设置数据库方法
VMware vCenter自带免费版的SQL Server 2005 Express,但此免费版数据库适合于小于5台ESX主机的小型部署.如果规模较大可以单独安装数据库系统进行配置,这里选择我独立安 ...
- UITableView初始
近期在自学IOS,看了黑马提供的视频,讲的很好.在此做些笔记,以供以后查阅.注明了知识来源应该不算侵权吧. 一 UITableView 1,数据展示的条件 1⃣️ UITableView的所有数据都是 ...
- mysql 写数据操作几次硬盘?
mysql 写数据步骤: 1:写入操作事物日志,持久化操作日志到磁盘,并且只是写在磁盘上一小块区域内的顺序io,不需要像随机io一样 在磁盘多个地方移动磁头 2:内存中事物日志持久化以后 ,写入的数 ...
- Eclipse导入JavaWeb项目报错:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
JavaWeb项目中写的JSP页面需要Web容器解析处理成HTML才能展示到前端浏览器,解析JSP需要Web容器.JSP页面顶端出现“红色”的报错信息:The superclass "jav ...
- CentOS 6.5上安装Python 2.7.9
CentOS 6.6自带的是Python 2.6.6,而编译llvm需要Python 2.7以上. checking for python... /usr/bin/python checking fo ...
- php 求两个文件的相对路径
网上看了一些这个题的一些解答方法,不过大多数就是对目前需求而定的,比如 $a = '/a/b/c/d/e.php'; $b = '/a/d/12/34/c.php'; getpath($a , $b ...
- ssh 文件传输
在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下载文件scp username@servername:/path/filename /var/www/local_dir(本地 ...
- Windows 批处理文件
窗口自动关闭:批处理文件执行完之后,窗口会自动关闭,若想执行完之后,窗口不自动关闭的话,在文件末尾添加1. 批处理文件执行完之后,窗口会自动关闭2. 若想执行完之后,窗口不自动关闭的话,在文件末尾添加 ...
- ubuntu14.04 reaver不能正常使用
原帖地址: ubuntu14.04 reaver不能正常使用 http://forum.anywlan.com/thread-282404-1-1.html (出处: http://www.anywl ...
- ESSENTIAL ENGLISH SLANG
airhead: stupid person. ace: excellent, great. Adam and Eve - Rhyming Slang for 'believe'. aggro - s ...