iOS UITextextField输入框被键盘遮挡解决方案

我们通常在项目开发中必定会遇到的一个问题就是键盘对输入框的遮挡问题,通常我们会有多种解决方案,最常被要求的产品需求就是输入框需要跟随键盘的移动而移动,如下例子:

uiTextFeild.gif

这样可以满足我们大多数需求,本篇文章的案例适合所有iPhone 和 iPad设备输入框的遮挡问题。

当然很多人可能会提出第三方库 IQKeyboardManager,这个库个人没使用过,原因是很多人说会产生一些莫名其妙的bug,所有这篇文章我就分享一下个人常用的解决方案。

通常我们需要监听键盘的弹出和收回 ,以及监听UITextextField 的代理方法,然后实现我们的需求。

[[NSNotificationCenter defaultCenter] 
addObserver:self selector:@selector(keyboardWillShow:) 
name:UIKeyboardWillShowNotification object:nil]; 

[[NSNotificationCenter defaultCenter] 
addObserver:self  selector:@selector(keyboardWillHide:) 
name:UIKeyboardWillHideNotification object:nil];

从UIKeyboardWillHideNotification 和 UIKeyboardWillShowNotification 的noti.userInfo中取出一个字典,我们可以获取到键盘的以下值:

UIKeyboardAnimationCurveUserInfoKey
UIKeyboardAnimationDurationUserInfoKey
UIKeyboardBoundsUserInfoKey
UIKeyboardCenterBeginUserInfoKey
UIKeyboardCenterEndUserInfoKey
UIKeyboardFrameBeginUserInfoKey
UIKeyboardFrameEndUserInfoKey
UIKeyboardIsLocalUserInfoKey

通过这几个key 我们可以获取到键盘的高度,可动画时间,以及动画曲线

这里我们需要关注textFeild 的代理方法:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

及当键盘开始编辑时候,我们修改self.view.frame,核心算法

// 键盘高度
CGFloat kbHeight = [[keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
//self.view.frame 的偏移量
// INTERVAL_KEYBOARD  输入框和键盘之间的间隔,可自定义
// textField.y +  textField.height 
CGFloat offset = (textField.frame.origin.y + textField.frame.size.height + INTERVAL_KEYBOARD) - (self.view.frame.size.height - kbHeight);

这里需要对offset 做容错处理:

if (offset > 0) {
       // 如果 INTERVAL_KEYBOARD 间隔过大,需要减少偏移量
        if (offset > kbHeight) {
            offset = kbHeight-50;
        }
        [self animationWithkeybooard:^{
            self.view.frame = CGRectMake(0, -offset, self.view.frame.size.width, self.view.frame.size.height);
        }];
    }else{
        [self animationWithkeybooard:^{
            self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
        }];
    }

这里的animationWithkeybooard 是对动画的一个简单的封装

- (void)animationWithkeybooard:(void (^)(void))animations{
    NSTimeInterval duration = [[keyboardInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    UIViewAnimationCurve curve = [[keyboardInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationCurve:curve];
    animations();
    [UIView commitAnimations];
}

需要注意一点是

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
- (void)keyboardWillShow:(NSNotification *)noti;

第一个方法回调早于第二个,这就会造成self.view.frame不能改变,首要在keyboardWillShow 动态调用一次第一个方法。

这样具体的逻辑以及全部完成了,有兴趣的可以下载一下Example自己尝试一下。

Example Github

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,026评论 3 119
  • 效果图如下: 思路分析: 当我们有很多输入框时,有时候键盘弹出来会遮挡着输入框。我们需要获取输入框和键盘相对于最外...
    Coder_Cat阅读 11,301评论 1 14
  • 墙墙,为什么还不出成绩好担心挂科。
    山工院表白墙阅读 206评论 0 0
  • 横笛池上空飞鹤,叶底秦筝流榖波。 晚日舒云舟过处,蝶仙漫舞影媻娑。 注:新韵 秦筝:筝,又称古筝、秦筝,约(公元前...
    幽小窗阅读 422评论 11 23
  • 乌夜啼 最后回眸 今别离,忆难忘,往日惆怅消黯事,至此终将绝。 ...
    冬窗夜雨阅读 245评论 0 0