项目中经常会遇到这样的问题:一个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避免键盘遮挡输入方案的更多相关文章

  1. 《React-Native系列》44、基于多个TextInput的键盘遮挡处理方案优化

    曾经写过两篇关于在ReactNative上处理键盘遮挡输入表单TextInput的情况.建议读者能够先看看 1.<React-Native系列>33. 键盘遮挡问题处理 2.<Rea ...

  2. iOS 处理键盘遮挡TextField、TextView问题

    之前处理键盘遮挡问题都是在每一个控制器进行单独处理,这样做真的是非常的费事,今天在做项目的时候就想到自己封装一个,记录一下这个“跌宕起伏”的过程. 思路是这样的:计算文本编辑控件Frame与键盘Fra ...

  3. iOS 键盘遮挡输入 解决办法

    .初始化及添加通知观察者 - (void)viewDidLoad { [super viewDidLoad]; self.tableView = [[UITableView alloc] initWi ...

  4. (iOS)关于键盘遮挡textfield问题

    记录一下自己经常遇到问题.使用textfield(textview).当输入框位置比较靠下时,弹出的键盘会遮挡输入框,这是就需要动态移动输入框编辑状态时self.view的位置, 自己经常用的方法有两 ...

  5. ZYKeyboardUtil 全自动处理键盘遮挡事件

    键盘遮盖输入控件或按钮在日常app开发中避之不及,考虑各种情况下UI各种嵌套,最后还要注册监听再获取指定键盘信息.我们可以通过键盘处理工具类ZYKeyboardUtil避繁就简,利用Block的方式处 ...

  6. iOS键盘遮挡输入框,输入区域自动上移

    在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹 ...

  7. iOS开发笔记11:表单键盘遮挡、浮点数价格格式化显示、省市区选择器、View Debugging

    1.表单键盘遮挡 应用场景为一个collectionView上有多个textfield.textView供用户填写信息. 之前输入项较少时,采取的方法比较粗暴,didSelectItemAtIndex ...

  8. iOS键盘遮挡问题解决办法

    iOS开发之“键盘遮挡输入框的解决办法”之一 -----键盘通知之前处理这种问题,总是在触发输入框编辑事件键盘弹出的时候,将当前的View整体向上移动,结束编辑又整体向下移,耗时耗力效率低. 在网上看 ...

  9. iOS学习——键盘弹出遮挡输入框问题解决方案

    在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发 ...

随机推荐

  1. CSS中常用中文字体转Unicode编码表

    中文名 英文名 Unicode Unicode 2 Mac OS 华文细黑 STHeiti Light [STXihei] \534E\6587\7EC6\9ED1 华文细黑 华文黑体 STHeiti ...

  2. JS--图片轮播效果

    搞了很长时间才弄清楚图片轮播效果的原理,理解各个事件发生的原因,浪费了这么长的时间,只怪自己的知识太过于薄弱.现将代码写下,供大家参看,如有不妥之处还望指出,大家一起学习. 功能: 1.点击左右两边的 ...

  3. Bundle类

    1.新建一个Bundle类 Bundle bundle=new Bundle();2.Bundle类中放入数据(key-value的形式,另一个Activity里面取数据的时候,通过key值找出对应的 ...

  4. MFC关于VS内存释放的定位

    全部在App中完成 1.在 App.h 头文件声明 #ifdef _DEBUGprotected:      CMemoryState m_msOld, m_msNew, m_msDiff;#endi ...

  5. GUI(主)线程与子线程之间的通信(用信号槽通讯)

    在主线程上,可以控制子线程启动,停止,清零 如果子线程启动的话,每一秒钟会向主线程发送一个数字,让主线程更新界面上的数字. 程序截图: 上代码: #include <QtGui> #inc ...

  6. android AudioRecorder简单心得

    1.如何创建一个有效的AudioRecorder实例 Android各种设备的采样频率不同,输入的声道数也不同,如果采用固定的采样频率和声道数,那么得到的AudioRecorder不一定能够正常初始化 ...

  7. 8.2.1.4 Index Merge Optimization 索引合并优化:

    8.2.1.4 Index Merge Optimization 索引合并优化: 索引合并方法是用于检索记录 使用多个 范围扫描和合并它们的结果集到一起 mysql> show index fr ...

  8. virtualbox端口转发

    端口转发:setting->network->adapter:attached to NAT.port forwarding rules->name    protocol     ...

  9. 【转】android ddms中查看线程释疑

    原文网址:http://www.mobiletrain.org/lecture/doc/android/2011-05/457.html 大家都用过ddm,如果你用ddms查看一个程序的所有线程,你会 ...

  10. 【转】Win8/8.1/Win7小技巧:揪出C盘空间占用的真凶

    原文网址:http://www.ithome.com/html/win8/55496.htm 不少使用Win8.Win8.1的用户不难发现,原先只占用20G大小的系统盘,随着使用时间的增加,C盘的磁盘 ...