iOS 多个UITextField切换,键盘遮挡输入框问题

2018-08-24  本文已影响305人  突刺刺

一.需求

单个界面,多个UITextField切换,要求始终在键盘之上,不被遮挡。

二.分析

解决方法:
这种情况很简单,只需监听KeyBoardUIKeyboardWillShowNotification/UIKeyboardWillHideNotification,就可以获取KeyBoard的高度和当前UITextField在屏幕中的位置。

解决方法:
KeyBoard不隐藏,UITextField来回切换,就没有UIKeyboardWillShowNotification/UIKeyboardWillHideNotification通知发送,如果KeyBoard类型没有变化,甚至监听UIKeyboardWillChangeFrameNotification也没用。
这个时候就要换一种方法获取KeyBoard的高度,和当前UITextField在屏幕中的位置。

三.代码

@implementation KKViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yjd_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yjd_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }

- (void)yjd_keyboardWillShow:(NSNotification *)notifi
{
    //获取键盘的高度
    NSDictionary *userInfo = [notifi userInfo];
    NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGFloat keyboardHeight = [aValue CGRectValue].size.height;//键盘的高度
    //获取键盘动画时间
    CGFloat time = [notifi.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    //获取当前第一响应状态的输入框
    UIWindow * keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIView *view = [keyWindow performSelector:@selector(firstResponder)];

    //输入框在当前屏幕的坐标y
    CGFloat maxY =  CGRectGetMaxY([view convertRect:view.bounds toView:[[[UIApplication sharedApplication] delegate] window]]);
    
    //判断是非遮挡当前输入框,小于0遮挡,大于或等于0没有
    CGFloat map = SCREEN_HEIGHT - maxY - keyboardHeight;
    if (map < 0)
    {
        [UIView animateWithDuration:time animations:^{
            self.view.transform = CGAffineTransformMakeTranslation(0, map);
        }];
    }
}

- (void)yjd_keyboardWillHide:(NSNotification *)notifi
{
    CGFloat time = [notifi.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    [UIView animateWithDuration:time animations:^{
        self.view.transform = CGAffineTransformIdentity;
    }];
}

- (void)dealloc
{
    [self.hud yjd_stopHud];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
@implementation KKViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yjd_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yjd_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }

- (void)yjd_keyboardWillShow:(NSNotification *)notifi
{
    //获取键盘的高度
    NSDictionary *userInfo = [notifi userInfo];
    NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGFloat keyboardHeight = [aValue CGRectValue].size.height;//键盘的高度
    //获取键盘动画时间
    CGFloat time = [notifi.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    //获取当前第一响应状态的输入框
    UIWindow * keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIView *view = [keyWindow performSelector:@selector(firstResponder)];

    //输入框在当前屏幕的坐标y
    CGFloat maxY =  CGRectGetMaxY([view convertRect:view.bounds toView:[[[UIApplication sharedApplication] delegate] window]]);
    
    //判断是非遮挡当前输入框,小于0遮挡,大于或等于0没有
    CGFloat map = SCREEN_HEIGHT - maxY - keyboardHeight;
    if (map < 0)
    {
        [UIView animateWithDuration:time animations:^{
            self.view.transform = CGAffineTransformMakeTranslation(0, map);
        }];
    }
}

- (void)yjd_keyboardWillHide:(NSNotification *)notifi
{
    CGFloat time = [notifi.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    [UIView animateWithDuration:time animations:^{
        self.view.transform = CGAffineTransformIdentity;
    }];
}

- (void)dealloc
{
    [self.hud yjd_stopHud];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

自定义KKTextField.m文件

#import "KKTextField.h"
@interface KKTextField()<UITextFieldDelegate>
@end
@implementation KKTextField

- (UIView *)yjd_findKeyBoard
{
    UIView *keyboardView = nil;
    NSArray *windows = [[UIApplication sharedApplication] windows];
    for (UIWindow *window in [windows reverseObjectEnumerator])//逆序效率更高,因为键盘总在上方
    {
        keyboardView = [self yjd_findKeyBoardInView:window];
        if (keyboardView)
        {
            return keyboardView;
        }
    }
    return nil;
}

- (UIView *)yjd_findKeyBoardInView:(UIView *)view
{
    for (UIView *subView in [view subviews])
    {
        if (strstr(object_getClassName(subView), "UIKeyboard"))
        {
            return subView;
        }
        else
        {
            UIView *tempView = [self yjd_findKeyBoardInView:subView];
            if (tempView)
            {
                return tempView;
            }
        }
    }
    return nil;
}

#pragma mark UITextFieldDelegate 事件
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    //获取textField在屏幕中的位置
    CGFloat maxY =  CGRectGetMaxY([textField convertRect:textField.bounds toView:[[[UIApplication sharedApplication] delegate] window]]);
   
  //获取KeyBoard
   UIView *view = [textField yjd_findKeyBoard];
    
    //判断是非遮挡当前输入框,小于0遮挡,大于或等于0没有
    CGFloat map = SCREEN_HEIGHT - maxY - view.frame.size.height;
    if (map < 0)
    {
        [UIView animateWithDuration:0.2 animations:^{
            textField.transform = CGAffineTransformMakeTranslation(0, map);
        }];
    }
    return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [UIView animateWithDuration:0.2 animations:^{
        textField.transform = CGAffineTransformIdentity;
    }];
}

上一篇 下一篇

猜你喜欢

热点阅读