iOS避免键盘遮挡输入方案
2016-05-20 11:24
447 查看
项目中经常会遇到这样的问题:一个tableView中有大量的textField,当点击屏幕底部的textfield时,由于键盘弹出挡住了textfield输入框里的内容,造成很差的用户体验,如下图,点击价格那一行,会出现图二这种效果(弹出的键盘完全遮盖了输入)。
图一:
图二:
解决思路:自定义一个textfield,声明一个公用方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight: 并实现它,这个方法的作用是调整controller的view的y值使整个view上移,让被点击的textfield显示出来,建议在controller的view的textfield的代理方法 -(void)textFieldDidBeginEditing: 中获取自定义的textfield,并调用它的此方法(开始编辑时就调整view的y值)。
第13行用到了键盘的高度keyboadHeight,所以我们还需要在控制器中得到键盘的高度。
当键盘弹出时,获取键盘高度,并将键盘高度传入定义好的block
之所以用block,是因为方法 - (void)textFieldDidBeginEditing: 被调用时,还没有获取到键盘高度,所以先将代码保存为block,等获取到键盘高度后再传入键盘高度,调用textfield的自适应键盘高度的方法 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight:
block中调用自定义textfield的 - (void)adjustTextFieldFrameWhenBeginEdtingWithView: keyBoardHeight: 方法,并把键盘高度作为参数传入自定义textfield。
键盘消失后,将调整后的view还原。
如此就完成了textfield的自适应,每次点击底部textfield,view会根据textfield的位置上移一段距离,不被键盘遮盖,效果如下:
图三:
图四:
附上demo代码:
控制器中代码:
自定义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 = 0; keyBoardY = [UIScreen mainScreen].bounds.size.height - keyboadHeight ; // 控制器view 要调整的高度 CGFloat adjustY = selfFrame.origin.y + selfFrame.size.height + MARGIN - keyBoardY; if (adjustY > 0) { // 调整高度大于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 = 0; } 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 = 0; } 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 = 0; } 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 = 0; i < 20; 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:0 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(50, (cell.height - cell.height - 2)/2, cell.width , cell.height - 2)];
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 = 0; keyBoardY = [UIScreen mainScreen].bounds.size.height - keyboadHeight ; // 控制器view 要调整的高度 CGFloat adjustY = selfFrame.origin.y + selfFrame.size.height + MARGIN - keyBoardY; if (adjustY > 0) { // 调整高度大于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 = 0; } completion:^(BOOL finished) { }]; } } @end
相关文章推荐
- Vickate_iOS_键盘监听
- iOS学习之——转场动画
- iOS开发 - 技巧 - 01 - 图片拉伸方式
- 窗口、视图、动画(16.5.20)
- IOS集成到支付宝
- [置顶] iOS长按识别图中二维码
- 根据ios或者安卓扫描二维码进行相应下载
- iOS学习之——一些常见的数据类型的转换
- IOS9需要升级提升的点
- iOS开发规范文档
- iOS开发-做项目中遇到的坑
- iOS 左右两列按钮之间进行连线
- iOS远程推送原理及实现过程
- IOS后台运行机制详解(二)
- GitHub 排名前 100 的安卓、iOS项目简介
- IOS后台运行机制详解(一)
- iOS数据持久化文件读写之偏好设置
- iOS IM开发建议(三)添加一个自定义键盘
- iOS Video Streaming(收集,整理)
- 基于iOS 的 VLC简单 Demo