美文网首页iOS开发实录iOS技术分享iOS进阶指南
ScrollView解决软键盘遮挡输入框问题

ScrollView解决软键盘遮挡输入框问题

作者: _浅墨_ | 来源:发表于2016-05-16 17:09 被阅读1518次

    一、原理

    如何在自己的代码中使用 content inset?当键盘在屏幕上时,有一个很好的用途:你想要设置一个紧贴屏幕的用户界面。当键盘出现在屏幕上时,你损失了几百个像素的空间,键盘下面的东西全都被挡住了。

    现在,scroll view 的 bounds 并没有改变,content size 也并没有改变(也不需要改变)。但是用户不能滚动 scroll view。考虑一下之前一个公式:content offset 的最大值是 content size 和 bounds 的差。如果他们相等,现在 content offset 的最大值是 {x:0, y:0}.

    现在开始出绝招,将界面放入一个 scroll view。scroll view 的 content size 仍然和 scroll view 的 bounds 一样大。当键盘出现在屏幕上时,你设置 content inset 的底部等于键盘的高度。

    scrollview

    这允许在 content offset 的最大值下显示滚动区域外的区域。可视区域的顶部在 scroll view bounds 的外面,因此被截取了(虽然它在屏幕之外了,但这并没有什么)。

    摘自:
    http://objccn.io/issue-3-2/

    二、示例

    - (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)viewDidDisappear:(BOOL)animated{
    
        // 记得一定要注销通知监听,否则有时会导致crash
        // 比如内存中两个类均收到通知,然后他们都想执行跳转,这个时候就crash了
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
      NSLog(@"%@", NSStringFromCGPoint(self.fgScrollView.contentOffset));
    }
    
    - (void)keyboardWillShow:(NSNotification *)notification {
    
      NSDictionary *info = [notification userInfo];
      CGSize keyboardSize = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    
      [UIView beginAnimations:nil context:NULL];
      [UIView setAnimationDuration:[info[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
      [UIView setAnimationCurve:[info[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
      [UIView setAnimationBeginsFromCurrentState:YES];
      
      UIEdgeInsets insets = UIEdgeInsetsMake(self.fgScrollView.contentInset.top, 0, keyboardSize.height, 0);
      self.fgScrollView.contentInset = insets;
      self.fgScrollView.scrollIndicatorInsets = insets;
      self.fgScrollView.contentOffset = CGPointMake(self.fgScrollView.contentOffset.x, self.fgScrollView.contentOffset.y + keyboardSize.height);
      
      [UIView commitAnimations];
    
    }
    
    - (void)keyboardWillHide:(NSNotification *)notification {
    
      NSDictionary *info = [notification userInfo];
    
      [UIView beginAnimations:nil context:NULL];
      [UIView setAnimationDuration:[info[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
      [UIView setAnimationCurve:[info[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
      [UIView setAnimationBeginsFromCurrentState:YES];
    
      UIEdgeInsets insets = UIEdgeInsetsMake(self.fgScrollView.contentInset.top, 0, 0, 0);
      self.fgScrollView.contentInset = insets;
      self.fgScrollView.scrollIndicatorInsets = insets;
      
      [UIView commitAnimations];
    
    }
    
    

    三、附:
    contentoffset vs contentinset

    四、demo下载地址

    相关文章

      网友评论

      • b12217fcb3f4:我在scrollView中放了一个tableVIew tableView中的TextView键盘用你dome里的方法还是要遮挡,这个该怎能弄,求大神指点
      • science_Lee:当我再次修改顶部的内容时,会不会跑到屏幕外面去
      • 5elephant:我的是swift写的,点击textfield时scrollview向上滚动了250.

        func textFieldDidBeginEditing(textField: UITextField) {
        scrollView.setContentOffset(CGPointMake(0, 250), animated: true)
        _浅墨_:@5elephant 设置contentInset比较好
      • FengxinLi:不错的方法。但是你的contentsize要和frame的大小相等才行?
        _浅墨_:@Fengxinliju 你试试哈,我没亲测

      本文标题:ScrollView解决软键盘遮挡输入框问题

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