zoukankan      html  css  js  c++  java
  • 有关UITextField被键盘遮挡的代码

    最近做项目开发,遇到了一个ios初学者都会遇到的问题,就是文本框被键盘遮盖了,而ios系统又不会自动给你换位置,这纠结我一段时间,先看一个百度出镜率比较高的方法

    -(void)textFieldDidBeginEditing:(UITextField *)textField
    {
        NSLog(@"did开始编辑");
        NSLog(@"kbHeight=%f",kbHeight);
        CGRect frame=textField.frame;
        //假设触摸点在键盘覆盖范围内,获取该点需要上移离开键盘覆盖的长度
        int offset=frame.origin.y+frame.size.height+32-(self.frame.size.height-kbHeight);
        NSLog(@"offset=%d",offset);
        if (offset>0) {
            self.frame=CGRectMake(0.0f, -offset, self.frame.size.width, self.frame.size.height);
        }
    }
    
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }
    
    -(void)textFieldDidEndEditing:(UITextField *)textField
    {
        NSLog(@"did结束编辑");
        self.frame =CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    }

    方法比较简单,为文本框添加委托,获得焦点时计算文本框到键盘顶部的距离然后改变文本框的frame,将其上移.但是该方法有很大的局限性,就是将文本框的高度定死,这就导致在应用横屏时UI布局会出现问题,而且当一个界面有多个文本框,切每一个文本框需要指定不同行为时,delegate这种做法就显得捉襟见肘了

    楼主现在做的一个小项目,一个界面有5-6个文本框,且需要支持横屏和竖屏切换,这样一来上述方法就明显不合适了,只能自己再琢磨.因为控件较多,用了UIScrollView控件,想一下常规思路就是添加键盘出现消息,在键盘出现时改变scrollView的contentOffSet,但实际操作过程中发现键盘出现时文本框为第一响应者,此时在与键盘消息绑定的方法中改变scrollview的contentOffSet会使文本框失去第一响应者资格,于是改变contentOffSet只能放弃,那就改变scrollView的frame吧

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotification object:nil];
    //关于这里为什么要接受willShow消息而不是DidShow消息,因为设计到scrollVoew位置的变化,会转变FirstResponder,因此选择WillShow消息
    - (void)keyboardWillShow:(NSNotification *)notification{
        NSDictionary * userInfo = [notification userInfo];
        CGSize kbSize=[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue].size;
        
        //获取键盘高度
        float keyboardHeight=0;
        if (kbSize.width<kbSize.height) {//无论横屏还是竖屏,键盘的高度始终小于宽度
            keyboardHeight=kbSize.width;
        }else{
            keyboardHeight=kbSize.height;
        }
        NSLog(@"键盘高度=%f",keyboardHeight);
    
        //获取第一响应者
        UITextField * _txtField;
        for (UIView * _view in scrollView.subviews) {
            if ([_view isFirstResponder] && [NSStringFromClass(_view.class) isEqualToString:@"UITextField"] ) {
                _txtField=(UITextField * )_view;
            }
        }
        NSLog(@"获取到的文本框信息%@",_txtField);
        
        CGRect rectInView=[scrollView convertRect:_txtField.frame toView:self];
        NSLog(@"在当前界面的坐标x=%f,y=%f,width=%f,height=%f,",rectInView.origin.x,rectInView.origin.y,rectInView.size.width,rectInView.size.height);
        
        float _viewHeight=self.frame.size.height;
        NSLog(@"当前view 的高度=%f",_viewHeight);
        float _moreHeight =_txtField.frame.origin.y+_txtField.frame.size.height-(_viewHeight-keyboardHeight);
        NSLog(@"需要上移的高度%f",_moreHeight);
        if (_moreHeight>0) {
            scrollView.frame=CGRectMake(0, -_moreHeight, scrollView.frame.size.width, scrollView.frame.size.height);
        }
    }
    
    -(void)keyboardWillHide:(NSNotification * )notification{
        scrollView.frame=CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
    }

    这里有必要说一下,关于获取键盘高度的代码,官方文档中提示可以用convertRect:fromWindow: 方法将键盘的坐标转换,但在实际操作过程中我发现无论应用为横屏还是竖屏状态,键盘的frame属性是以iphone竖屏时的屏幕左下角为原点的,这也导致了用convertRect:fromWindow: 方法转换到scrollView中的数据无法使用(可能楼主比较小白,没怎么看书,这也得实践才知道,求轻喷),但在实际操作中楼主发现无论横屏还是竖屏状态,ipone虚拟键盘的宽度是种比高度要大,于是动态获取键盘高度问题瞬间解决了,然后就是简单的计算frmae需要上移多少高度才能正好到达键盘上方了,当然你得先判断一下键盘出现以后是否会遮挡到文本框,如果没有遮盖就不用多此一举移动scrollView了.

    这是楼主的第一个正式项目,感觉学到了不少,纯小白作品,大牛无视之.

  • 相关阅读:
    linux 命令展示该目录下的所有子目录及文件结构 tree
    ssh-keygen
    centos安装git
    spring-boot parent变更为依赖方式
    centos docker compose安装
    UML——活动图
    UML——构件图
    UML——部署图
    UML——用例图
    UML——关系
  • 原文地址:https://www.cnblogs.com/candr/p/3435941.html
Copyright © 2011-2022 走看看