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开发 ...
随机推荐
- VC Windows系统服务创建代码
Windows系统服务创建步骤,常用类封装,废话不多说,直接上代码 // ServceDemo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...
- php 设置报错等级
定义和用法: error_reporting() 设置 PHP 的报错级别并返回当前级别. 函数语法: error_reporting(report_level) 如果参数 level 未 ...
- 武汉科技大学ACM:1004: Lake and Island
Problem Description 北园孩子的专属福利来啦~学校从北区宿舍到湖心岛修建了一条通道让北园的同学们可以上去一(kuang)同(xiu)玩(en)耍(ai),这一天,IcY向ahm001 ...
- div边框阴影的实现【转载】
box-shadow:阴影水平偏移值(可取正负值): 阴影垂直偏移值(可取正负值):阴影模糊值:阴影颜色: Firefox支持Box Shadow(阴影):-moz-box-shadow:2px 2p ...
- 基于PHP和mysql的自动生成表单
开发背景:公司要求管理系统能够由管理员在前台页面管理系统表单,能够对表单进行增删改查基本操作,表单的各个字段都可以被修改.删除,可以添加新的字段,并且不影响系统正常运行,前台表单展示要由系统自动处理, ...
- 如何使用cocos2dx-jsbinding 来处理分辨率适配
首先说点题外话,对于任何大型项目来说,coding的规范重要,在cocos2dx-jsbinding这个框架中,javascript是一个绝对核心的脚本语言,99%的游戏逻辑都由js完成.脚本的编写量 ...
- HTML5数据存储
介绍两种对象使用方法: sessionStorage方法如果关闭了浏览器,这个保存的数据就丢失. 1.sessionStorage 保存数据:sessionStorage.setItem(key,va ...
- Symfony2源码分析——启动过程1
本文通过阅读分析Symfony2的源码,了解Symfony2启动过程中完成哪些工作,从阅读源码了解Symfony2框架. Symfony2的核心本质是把Request转换成Response的一个过程. ...
- php错误处理和php异常处理机制
php错误处理 当我们开发程序时,有时候程序出现了问题,我们就可以用以下几种办法找出错误. 开发阶段:开发时输出所有的错误报告,有利于我们进行程序调试 运行阶段:我们不要让程序输出任何一种错误报 ...
- 转:单片机C语言中的data,idata,xdata,pdata,code
从数据存储类型来说,8051系列有片内.片外程序存储器,片内.片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code.data.xdata.idata以及根据51系列特点而设定的 ...