/ IOS

UITextField 随键盘高度自适应

  在开发APP过程中,不免会遇到页面需要多个 UITextField 的需求,那么问题来了:当输入框过多时,弹起键盘会遮盖住输入框,或者需要依次点击输入框才能输入。用户的输入体验非常差。为解决这个问题,我们让输入框跟随键盘自动调整高度,并且点击回车键自动跳转到下一个输入框进行输入。

具体效果如图:


需求分析:

  简单分析一下:

  1. 点击输入框时,输入框随着键盘弹起,自动调整高度,使输入框位于键盘上方。
  2. 点击回车,自动切换到下一个输入框进行输入,同时调整输入框高度。

为了使输入框能够上下滑动,这里将所有 UITextField 放在一个 scrollview 上,然后添加键盘监听事件,当用户点击输入框时,触发键盘弹起,此时调整scrollView 的 contentOffset,使输入框正好位于键盘上方。

添加键盘监听:

 [[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 {
    //获取键盘高度,在不同设备上,以及中英文下是不同的
    CGFloat kbHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
    _keyBoardHeight = kbHeight;
    [self boardAutoAdjust:kbHeight];
}

 - (void)keyboardWillHide:(NSNotification *)notify {
    // 键盘动画时间
    _keyBoardHeight = 0;
    [self.board setContentOffset:CGPointMake(0,-64) animated:YES];
}

UITextField 代理事件:

 - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    
    NSLog(@"=== %@", [NSValue valueWithCGRect:textField.frame]);
    self.fistField = textField;
    
    if (_keyBoardHeight > 0) {
        [self boardAutoAdjust:_keyBoardHeight];
    }
    return YES;
}

scrollview 偏移量计算

  scrollView 需要偏移的量 =页面总高度 - 输入框高度 - 键盘高度,当输入框高于键盘时,偏移量小于零,反之,偏移量大于零。

偏移量计算方法:

- (void)boardAutoAdjust:(CGFloat)keyboardHeight {
    
    if (self.fistField) {
        
        CGRect rec = _fistField.frame;
        
        CGFloat max_y = CGRectGetMaxY(rec);
        
        CGFloat b_offset = self.view.height - max_y - keyboardHeight;
        
        CGPoint point = self.board.contentOffset;
        point.y = -b_offset;
        
        [self.board setContentOffset:point animated:YES];
    }
}

键盘回车事件

  当点击键盘回车时,自动跳转到下一个输入框进行输入,最后一个输入框点击回车时,收起键盘,整体回到原先的布局高度。

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    
    if (textField.returnKeyType == UIReturnKeyNext) {
        
        [textField resignFirstResponder];
        UITextField *next = [self.textfields objectAtIndex:(textField.tag + 1)];
        [next becomeFirstResponder];
        
    } else if (textField.returnKeyType == UIReturnKeyDone) {
        
        [textField resignFirstResponder];
    }
    
    return YES;;
}

demo链接