当一个页面有多个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










网友评论