Xcode 6:当键盘显示的滚动视图高于所需的滚动视图

时间:2014-09-19 03:26:35

标签: keyboard scrollview xcode6

我刚刚安装了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中,视图滚动得更高,超出了视图限制。即使我选择了未被键盘隐藏的文本字段,它也会滚动。有谁知道影响这个的新版本中有哪些变化?非常感谢!

4 个答案:

答案 0 :(得分:1)

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

似乎在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 Portrait

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

答案 1 :(得分:1)

看起来它与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];
    }

}

干杯,

答案 2 :(得分:1)

根据 Igor Tupitsyn 的解决方案,我已经编写了此代码,该代码适用于 iOS7 iOS8

我已经成功测试了

  • 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键盘提供的配件视图时

希望它有所帮助!

答案 3 :(得分:0)

我建议使用KeyboardHandler

只需一行代码即可帮助我正确处理键盘!