MENU

iOS键盘遮挡问题

October 6, 2016 • Read: 183 • iOS

前言

  • 今天在写实验室项目的时候,突然发现了点击靠近屏幕下部UITextFiled 的时候,键盘弹起会挡住输入框。在网上找了很多教程,大多数是把视图弹起高度写死,或者是没有对不需要弹起的输入框进行了错误的视图弹起,导致靠上的输入框移出视图。但是!在IOS10中不同键盘高度是不同的!不同手机型号高度也不同!所以需要利用通知来动态获取键盘高度!
  • 先来看一下解决问题之后的Demo:
    键盘遮挡demo.gif

问题解决步骤

  • 为了方便,我直接在storyBoard中拖了3个UITextField控件,两个靠下,一个靠上。
  • 解决问题思路历程:

    • 首先是在注册键盘出现和隐藏通知的时候,分别添加两个方法,一个是视图弹起,一个是视图弹回。但是这个方法的缺陷是无论输入框在哪里,只要键盘弹起,视图必定上弹,这就导致了靠视图上部的输入框也会弹起,所以这个方案PASS掉。
    • 另一种方案是通过通知获取到键盘高度,然后在UITextField 的代理方法(void)textFieldDidBeginEditing:(UITextField *)textField中首先对textField.frame.origin.y和键盘高度的差值进行判断,如果差值大于0则上弹,如果小于0则不进行变化。视图弹回则在(void)textFieldDidEndEditing:(UITextField *)textField中进行处理。但是!!经过实际验证,textField的代理方法的执行在键盘通知之前,如图:
      所以这个方案也PASS掉。
    • 随后在网上查找解决方法,发现了iOS 导航栏覆盖问题这篇博文,为我提供了思路。

    ==可以利用一个对象来暂时保存被点击的UItextFeild,在通知调用方法的时候,进行输入框y值的判断,从而决定是否要更改视图。==

  • 完整代码如下:
//
//  ViewController.m
//  键盘遮挡问题
//
//  Created by 柳钰柯 on 2016/11/6.
//  Copyright © 2016年 柳钰柯. All rights reserved.
//
#import "ViewController.h"

@interface ViewController ()<UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *textFieldOne;
@property (weak, nonatomic) IBOutlet UITextField *textFieldTwo;
@property (weak, nonatomic) IBOutlet UITextField *testField;
/** 暂时保存当前正在编辑的textField */
@property (strong, nonatomic) UITextField *tmpTextField;
/** 键盘尺寸 */
@property (assign, nonatomic) CGSize kbSize;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 注册通知中心
    [self registerForKeyboardNotifications];

    // 设置代理
    self.textFieldOne.delegate = self;
    self.textFieldTwo.delegate = self;
    self.testField.delegate = self;
}

- (void)viewWillDisappear:(BOOL)animated{
    // 视图消失时移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

// 键盘弹回
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}

#pragma mark - 注册键盘通知中心获取键盘高度
// 注册键盘的通知中心
- (void)registerForKeyboardNotifications{
    // 键盘出现时的通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    // 键盘隐藏时的通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

// 键盘弹起,视图上弹
- (void)keyboardWillShow:(NSNotification *)aNotification{
    NSDictionary *info = [aNotification userInfo];
    // kbSize键盘尺寸
    self.kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    NSLog(@"-----------------键盘弹起---------------");

    // 当前视图尺寸
    CGRect currentFrame = self.view.frame;
    CGFloat change = self.kbSize.height;
    currentFrame.origin.y = currentFrame.origin.y - change;

    // 弹起视图
    if (self.view.frame.origin.y >=0&&self.tmpTextField.frame.origin.y - change >0) {
        self.view.frame = currentFrame;
    }
}

// 键盘弹回,视图弹回
- (void)keyboardWillHide:(NSNotification *)aNotification{
    NSDictionary *info = [aNotification userInfo];
    // kbSize键盘尺寸
    self.kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    NSLog(@"键盘高度:%f",self.kbSize.height);

    // 当前视图尺寸
    CGRect currentFrame = self.view.frame;
    CGFloat change = self.kbSize.height;
    currentFrame.origin.y = currentFrame.origin.y + change;

    // 恢复视图
    if (self.view.frame.origin.y <0) {
        self.view.frame = currentFrame;
    }
}

#pragma mark - <UITextFieldDelegate>
- (void)textFieldDidBeginEditing:(UITextField *)textField{

    NSLog(@"-----------------textFieldDidBeginEditing---------------");
    self.tmpTextField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
    self.tmpTextField = nil;
}
@end

最后

  • 感谢Halamyc博主提供的思路。
  • 如有错误,欢迎指正。随意转载,注明出处即可。
Tags: iOS开发
Archives QR Code
QR Code for this page
Tipping QR Code