美文网首页
TextField工具类

TextField工具类

作者: 霸_霸霸 | 来源:发表于2018-06-20 14:48 被阅读3次

当一个页面有多个TextField的时候, 我们往往会因为弹出键盘遮挡TextField, 如果每一个TextField都要写一遍NSNotification和两个方法(willShow, willHide)太麻烦, 所以写一个工具类来解决这个问题.

两种情况:

情况一: 为单个TextField添加上移功能

情况二: 为某个页面上的所有的TextField添加上移功能

思路: 添加观察者, 观察键盘即将出现或者收起;让TextField的根视图偏移, 而不是让textField偏移

//为textField添加监听
- (void)addNotificationToTextField{
    [[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 *)notification {
    //获取键盘高度
    float h = CGRectGetHeight([[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]);
    //获取键盘弹出所需时间
    float duration = [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    //获取第一响应者
    UITextField *firstResponderTextField = [self findFirstResponder];
    //如果键盘弹起时会遮挡某个textField, 让页面上移
    if (SCREEN_HEIGHT - h - firstResponderTextField.frame.origin.y - firstResponderTextField.frame.size.height < 0) {
        [UIView animateWithDuration:duration animations:^{
            //找到根视图
            [self findRootView];
            [rootView setFrame:CGRectMake(0, SCREEN_HEIGHT - h - firstResponderTextField.frame.origin.y - firstResponderTextField.frame.size.height - 20, CGRectGetWidth(rootView.frame), CGRectGetHeight(rootView.frame))];
        }];
    }
}

//键盘将要隐藏
- (void)keyBoardWillHide:(NSNotification *)notification {
    
    float duration = [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    [UIView animateWithDuration:duration animations:^{
        [rootView setFrame:CGRectMake(0, 0, CGRectGetWidth(rootView.frame), CGRectGetHeight(rootView.frame))];
    }];
}

开放的接口

@implementation UIView (KeyBoardAdjust)

UIView *rootView;
NSMutableArray *tfs;

//为单个TextField添加上移功能
- (void)adjustFrameWithKeyBoard {
    [self addNotificationToTextField];
//    [(id)self setDelegate:self];
}

//为页面上的所有TextField添加上移功能
- (void)adjustAllTextFieldsWithKeyBoard {
    if (!tfs) {
        tfs = [NSMutableArray array];
    }else {
        [tfs removeAllObjects];
    }
    [self addAllTheTextFieldsInPage:[self findRootView] IntoArray:tfs];
}

//移除某个TextField
- (void)removeKeyBoardAdjust {
    [tfs removeObject:self];
    [self removeKeyboardNotifications];
}

//为当前页面所有的TextField移除该功能
- (void)removePageKeyBoardAdjust {
    NSMutableArray *tempArray = [NSMutableArray array];
    [self addAllTheTextFieldsInPage:[self findRootView] IntoArray:tempArray];
    [tfs removeObjectsInArray:tempArray];
    [self removeKeyboardNotifications];
}

一些工具方法

//将页面上的所有的TextField添加到数组tfs中, 并给每个TextField添加监听
- (void)addAllTheTextFieldsInPage:(UIView *)rootView IntoArray:(NSMutableArray *)textFieldArray {
    for (UIView *view in rootView.subviews) {
        if (view.subviews.count > 0) {
            [self addAllTheTextFieldsInPage:view IntoArray:textFieldArray];
        }
        if ([view isKindOfClass:[UITextField class]]) {
            [textFieldArray addObject:view];
//            [(id)view setDelegate:self];
            [view addNotificationToTextField];
        }
    }
}

//找到当前页面的根视图
- (UIView *)findRootView {
    UIView *view = self;
    UIView *superView;
    while (true) {
        superView = view.superview;
        if (superView == nil) {
            superView = view;
            break;
        }else {
            view = superView;
        }
    }
    return rootView = superView;
}

//找到第一响应者
- (UITextField *)findFirstResponder {
    __block UITextField *firstResponderTextField = nil;
    [tfs enumerateObjectsUsingBlock:^(UITextField *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isFirstResponder]) {
            firstResponderTextField = obj;
            *stop = YES;
        }
    }];
    return firstResponderTextField;
}

//点击空白部分收起键盘
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [self endEditing:YES];
    //如果用下面的方法会导致无法选择文字
    //[[self findFirstResponder] resignFirstResponder];
    
}

//移除监听
- (void)removeKeyboardNotifications {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

使用方法

    UITextField *tf0 = [[UITextField alloc]initWithFrame:CGRectMake(100, 250, 150, 50)];
    [self.view addSubview:tf0];
    tf0.borderStyle = UITextBorderStyleLine;
    
    UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(100, 450, 150, 50)];
    [self.view addSubview:tf];
    tf.borderStyle = UITextBorderStyleLine;
    
    UITextField *tf1 = [[UITextField alloc]initWithFrame:CGRectMake(100, 560, 150, 50)];
    [self.view addSubview:tf1];
    tf1.borderStyle = UITextBorderStyleLine;
    [self.view adjustAllTextFieldsWithKeyBoard];

效果

1.gif

相关文章

网友评论

      本文标题:TextField工具类

      本文链接:https://www.haomeiwen.com/subject/ivhxyftx.html