【问题标题】:Xcode 6: scroll view when the keyboard is shown scrolls higher than neededXcode 6:显示键盘时的滚动视图滚动高于所需
【发布时间】:2014-11-13 13:47:57
【问题描述】:

我刚刚安装了 Xcode 6.0.1。 当键盘隐藏文本框时,我的应用程序使用以下方法向上滚动视图。它与 Xcode 5 配合得很好:

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect frame = self.scrollView.frame;

    // Depending on the orientation, the application chooses height or width of the keyboard to scroll
    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
        frame.size.height -= kbSize.height;

    }else{
        frame.size.height -= kbSize.width;
    }

    CGPoint fOrigin = activeField.frame.origin;
    fOrigin.y -= self.scrollView.contentOffset.y;
    fOrigin.y += activeField.frame.size.height;
    if (!CGRectContainsPoint(frame, fOrigin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y + activeField.frame.size.height - frame.size.height);
        [self.scrollView setContentOffset:scrollPoint animated:YES];
    }
}

但是在 Xcode 6 中,视图滚动得更高,远远超出了视图限制。即使我选择了未被键盘隐藏的文本字段,它也会滚动。有谁知道影响这个的新版本中发生了什么变化?非常感谢!

【问题讨论】:

    标签: keyboard scrollview xcode6


    【解决方案1】:

    基于 Igor Tupitsyn 的解决方案,我编写了这段代码,适用于 iOS7iOS8

    我已经测试成功了

    • iPhone6 (iOS 8.0.2)
    • iPhone5S (iOS 8.0)
    • iPhone5 (iOS 7.1.2)

    //initialization in your init method
    
    self.handledScrollView = <YOUR SCROLL VIEW>;
    self.handledScrollviewOldContentInset = UIEdgeInsetsZero;
    self.handledScrollviewOldScrollIndicatorInset = UIEdgeInsetsZero;
    self.isKeyboardShown = NO;
    
    
    -(void) myKeyboardWillShow:(NSNotification *)note
    {
        if (!self.handledScrollView)
            return;
    
        CGSize kbSize = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    
        if (!self.isKeyboardShown){
            self.handledScrollviewOldContentInset = self.handledScrollView.contentInset;
            self.handledScrollviewOldScrollIndicatorInset =     self.handledScrollView.scrollIndicatorInsets;
        }
    
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        NSValue* valAnimDuration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
        NSTimeInterval duration = 0;
        [valAnimDuration getValue:&duration];
        [UIView setAnimationDuration:duration];
    
        // save current inset state
        self.handledScrollView.contentInset = contentInsets;
        self.handledScrollView.scrollIndicatorInsets = contentInsets;
    
        // Scroll the table view to see the TextField just above the keyboard
        if (self.activeTextFieldInScrollView && !self.isKeyboardShown)
        {
            CGRect textFieldRect = [self.handledScrollView convertRect:((UIView*)self.activeTextFieldInScrollView).bounds fromView:self.activeTextFieldInScrollView];
            [self.handledScrollView scrollRectToVisible:textFieldRect animated:NO];
        }
    
        [UIView commitAnimations];
    
        self.isKeyboardShown = YES;
    
    }
    
    -(void) myKeyboardWillHide:(NSNotification *)note
    {
        if (!self.handledScrollView)
            return;
    
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        NSValue* valAnimDuration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
        NSTimeInterval duration = 0;
        [valAnimDuration getValue:&duration];
        [UIView setAnimationDuration:duration];
    
        // restore insets and reset old state
        self.handledScrollView.contentInset = self.handledScrollviewOldContentInset;
        self.handledScrollView.scrollIndicatorInsets = self.handledScrollviewOldScrollIndicatorInset;
    
        self.handledScrollviewOldContentInset = UIEdgeInsetsZero;
        self.handledScrollviewOldScrollIndicatorInset = UIEdgeInsetsZero;
    
        [UIView commitAnimations];
    
        self.isKeyboardShown = NO;
    
    }
    

    这也适用于不同的键盘尺寸(标准、情感和任何自定义键盘),并且当您用手指显示或隐藏默认 iOS8 键盘提供的附件视图时也可以正常工作

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题 - 当键盘出现时,文本字段从屏幕顶部飞出!

      似乎在 iOS8.0 中,与 iOS 7.0.3 相比,键盘尺寸发生了翻转。这是我的 iPad 应用程序的一些输出,它在横向(仅在横向)中运行:

      iOS 7.0.3:

       <0x7c4b4600 EditSignViewController.m:(1060)> the text fieldis <UITextField: 0x7b2dbd10; frame = (611 473; 90 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7b2dc850>; layer = <CALayer: 0x7b2dbe50>>
       <0x83174f10 MasterSignFilterViewController.m:(461)> kbsize is {352, 1024}
       <0x83174f10 MasterSignFilterViewController.m:(462)> kbsize.height is: 1024.000000
       <0x83174f10 MasterSignFilterViewController.m:(463)> kbsize.width is: 352.000000
      

      这是相同的输出,但运行的是 iOS 8:

       <0x7d96d000 EditSignViewController.m:(1060)> the text fieldis <UITextField: 0x80af8c40; frame = (611 473; 90 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x851ab520>; layer = <CALayer: 0x80af8d80>>
       <0x7c570f20 MasterSignFilterViewController.m:(422)> kbsize is {1024, 352}
       <0x7c570f20 MasterSignFilterViewController.m:(423)> kbsize.height is: 352.000000
       <0x7c570f20 MasterSignFilterViewController.m:(424)> kbsize.width is: 1024.000000`
      

      在我看来,当设备旋转时,键盘尺寸坐标现在在 iOS 8 中旋转,而在 iOS 7 中它是静态的...

      我做了一个快速测试 - MasterDetail iPad 应用程序,带有文本字段的 Scrollview,注册 KB 通知并在 KB 出现在屏幕上时吐出一些详细信息。

      相关代码:

      - (void)keyboardWasShown:(NSNotification*)aNotification
      {
          NSLog(@"KB coming up!");
          NSDictionary* info = [aNotification userInfo];
          CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
          NSLog(@"kbsize is %@", NSStringFromCGSize(kbSize));
          NSLog(@"kbsize.height is: %f", kbSize.height);
          NSLog(@"kbsize.width is: %f", kbSize.width);
      }
      

      看起来 iOS 8 KB 有点高(由于显示了预测结果),现在当屏幕处于横向时会旋转它的尺寸:

      8.0 横向

      2014-09-25 11:32:45.511 BKTest[2788:223360] KB coming up!
      2014-09-25 11:32:45.512 BKTest[2788:223360] kbsize is {1024, 391}
      2014-09-25 11:32:45.512 BKTest[2788:223360] kbsize.height is: 391.000000
      2014-09-25 11:32:45.512 BKTest[2788:223360] kbsize.width is: 1024.000000
      

      7.0.3 横向

      2014-09-25 11:34:43.677 BKTest[2891:70b] KB coming up!
      2014-09-25 11:34:43.677 BKTest[2891:70b] kbsize is {352, 1024}
      2014-09-25 11:34:43.677 BKTest[2891:70b] kbsize.height is: 1024.000000
      2014-09-25 11:34:43.678 BKTest[2891:70b] kbsize.width is: 352.000000
      

      iOS 8.0 纵向

      2014-09-25 11:29:43.235 BKTest[2741:220963] KB coming up!
      2014-09-25 11:29:43.237 BKTest[2741:220963] kbsize is {768, 303}
      2014-09-25 11:29:43.238 BKTest[2741:220963] kbsize.height is: 303.000000
      2014-09-25 11:29:43.238 BKTest[2741:220963] kbsize.width is: 768.000000
      

      7.0.3 纵向

      2014-09-25 11:34:19.796 BKTest[2891:70b] KB coming up!
      2014-09-25 11:34:19.797 BKTest[2891:70b] kbsize is {768, 264}
      2014-09-25 11:34:19.797 BKTest[2891:70b] kbsize.height is: 264.000000
      2014-09-25 11:34:19.797 BKTest[2891:70b] kbsize.width is: 768.000000
      

      【讨论】:

      • meierjo,你是对的。下面,我展示了我在 iOS8 中是如何解决的。但现在它与 iOS7 不兼容。
      【解决方案3】:

      看起来它与 iOS7 或 iOS8 兼容。在两者中都不能很好地工作。无论如何,这在 iOS8 中解决了;

      在 viewDidLoad 中

      // Scroll view size
      self.scrollView.contentSize = CGSizeMake(1024, 768);
      

      keyboardWasShown 方法:

      - (void)keyboardWasShown:(NSNotification*)aNotification
      {
      
          info = [aNotification userInfo];
          CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
      
          UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
          self.scrollView.contentInset = contentInsets;
          self.scrollView.scrollIndicatorInsets = contentInsets;
      
          CGRect aRect = self.scrollView.frame;
      
          aRect.size.height -= kbSize.height;
          CGPoint origin = activeField.frame.origin;
          origin.y -= self.scrollView.contentOffset.y;
      
          if (!CGRectContainsPoint(aRect, origin) ) {
              CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y + activeField.frame.size.height - aRect.size.height);
              [self.scrollView setContentOffset:scrollPoint animated:YES];
          }
      
      }
      

      干杯,

      【讨论】:

        【解决方案4】:

        我推荐使用KeyboardHandler

        仅用 1 行代码就可以帮助我正确处理键盘!

        【讨论】:

          猜你喜欢
          • 2015-10-19
          • 1970-01-01
          • 2014-11-23
          • 2013-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多