美文网首页iOS_UIkitiOS开发历程iOS 遇到的问题
iOS简单的键盘弹出防遮挡效果

iOS简单的键盘弹出防遮挡效果

作者: 赤脊山的豺狼人 | 来源:发表于2016-03-08 16:36 被阅读2637次

    9.27更新:

    新项目中重新对键盘弹出的效果进行了封装,只需要三步就可以完成相关操作,并且支持TextView了。

    Git地址,如果好用请给个star,非常感谢!

    添加观察者
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.view addKeyboardNotification];
    }
    
    隐藏键盘操作
    [[self.view getIsEditingText] resignFirstResponder];
    
    移除观察者
    - (void)dealloc {
        [self.view removeKeyboardNotification];
    }
    

    正文:

    之前项目中遇到键盘弹出遮挡输入框时, 都是使用三方库DaiDodgeKeyboard进行界面上移动画, 这个三方库很方便, 但是有时候会出现如tableview.tableFooterView变短、大屏适配失效等非常诡异的情况, 所以本狼参考着网上资料自己动手实现了一个简单的效果.

    • 添加一下键盘的通知, 并记得移除
    - (void)viewDidLoad {
        [super viewDidLoad];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    
    • 写一个方法取到编辑状态下的textfield
    - (void)getIsEditingView:(UIView *)rootView {
        for (UIView *subView in rootView.subviews) {
            if ([subView isKindOfClass:[UITextField class]]) {
                if (((UITextField *)subView).isEditing) {
                    self.editingTextField = subView;
                    return;
                }
            }
            [self getIsEditingView:subView];
        }
    }
    
    • 计算已经拿到的textfield在屏幕中的位置
    - (CGFloat)screenViewYValue:(UIView *)textfield {
        CGFloat y = 0;
        for (UIView *view = textfield; view; view = view.superview) {
            y += view.frame.origin.y;
            if ([view isKindOfClass:[UIScrollView class]]) {
                // 如果父视图是UIScrollView则要去掉内容滚动的距离
                UIScrollView* scrollView = (UIScrollView*)view;
                y -= scrollView.contentOffset.y;
            }
        }
        return y;
    }
    

    因为我们不可能凡是textfield就上移, 所以要拿到位置再进行判断.

    • 最后针对拿到的这个位置来进行视图上移处理, 也就是通知执行的方法
    - (void)keyboardWillShow:(NSNotification *)noti {
        // 拿到正在编辑中的textfield
        [self getIsEditingView:self.view];
        // textfield的位置
        CGFloat viewY = [self screenViewYValue:self.editingTextField];
        // 键盘的Y值
        NSDictionary *userInfo = [noti userInfo];
        NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
        CGFloat keyboardEndY = value.CGRectValue.origin.y;
        // 动画
        NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
        [UIView animateWithDuration:duration.doubleValue animations:^{
            if (viewY+30 > keyboardEndY) {
                CGRect rect = self.tableView.frame;
                rect.origin.y += keyboardEndY - (viewY+30);
                self.tableView.frame = rect;
            }
        }];
    }
    
    • 键盘收起方法就比较简单了, 直接复位即可
    - (void)keyboardWillHide:(NSNotification *)noti {
        CGRect rect = self.tableView.frame;
        rect.origin.y = 0;
        self.tableView.frame = rect;
    }
    

    至此就基本实现了键盘弹出的动画效果, 可能还要具体需求具体分析, 不过一般场景已经够用, 其中-(CGFloat)screenViewYValue:方法是一个系列的, 本狼是写在UIView的类别里, 这里为了方便展示就单独拿了出来, 建议还是将方法整理写到类别中.

    关注豺狼的订阅号, 更新的新文章会第一时间收到通知~

    相关文章

      网友评论

      • Yaanco:我的textfield放在scrollview上,出现了问题,键盘退下后位置没有复位,,
        Bc_wh1te_Le1:+1 uitableview上的 也一样 收起键盘 所有控件上移
      • 奔哥小木屋:测试了 果然可以 不过只能用于textField, 有没有关于textView的?
        奔哥小木屋:@赤脊山的豺狼人 抽空封装一个textView和textField的 就齐全了 哈哈
        赤脊山的豺狼人:@偶是子树 这两天发一个封装好的类别上来,之前项目太忙一直没整理
      • Cyandev:没用用commitAnimation提交动画
      • Liberalism:源代码能不能让我看看,这样不知道该如何下手
      • Liberalism:我一会儿去试试

      本文标题:iOS简单的键盘弹出防遮挡效果

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