显示键盘时将UITextField滚动到视图中

时间:2013-04-04 03:28:35

标签: iphone scroll uitextfield iphone-softkeyboard

我正在撰写一款针对iOS 6.1的应用。我试图按照Apple doc关于如何在键盘遮挡的情况下将UITextField滚动到视图中。问题是Apple用于计算滚动点的文档算法效果不佳。我的计算滚动点的算法效果稍好一些,但偏离了70像素。计算滚动点的正确方法是什么?

下面你可以看到,从左到右,我在键盘显示之前的视图,滚动后使用Apple算法计算滚动点的视图,以及使用我的算法滚动计算滚动点后的视图。 (该网格中的每个方格都是25像素乘25像素。)

enter image description here

这是我正在使用的代码。请注意#if APPLE_WAY块。

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

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    self.view.contentInset = contentInsets;
    self.view.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your application might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, self.activeField.frame.origin) ) {

#if APPLE_WAY
        CGPoint scrollPoint = CGPointMake(0.0, self.activeField.frame.origin.y-kbSize.height);
#else
        CGFloat offset = self.activeField.frame.origin.y;

        //TODO: Why is this off by 70?
        offset = offset - 70;

        CGPoint scrollPoint = CGPointMake(0.0, offset);
#endif
        [self.view setContentOffset:scrollPoint animated:YES];
    }
}

3 个答案:

答案 0 :(得分:2)

您只需将偏移量设置为键盘的高度:

CGFloat offset = kbSize.height;
CGPoint scrollPoint = CGPointMake(0.0, offset);
[self.view setContentOffset:scrollPoint animated:YES];

希望这会有所帮助

答案 1 :(得分:1)

有几种方法可以做到这一点。鉴于你的情况,我会做这样的事情:

- (void)keyboardWasShown:(NSNotification *)aNotification
{
    NSDictionary* 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;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your application might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, self.activeField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, self.activeField.frame.origin.y-kbSize.height);
        [self.scrollView setContentOffset:scrollPoint animated:YES];
    }
}

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

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;

    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, self.activeField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0, 0);
        [self.scrollView setContentOffset:scrollPoint animated:YES];
    }
}

然后,在你的viewDidLoad方法中:

[[NSNotificationCenter defaultCenter] addObserver:self
                                     selector:@selector(keyboardWasShown:)
                                         name:UIKeyboardDidShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

答案 2 :(得分:0)

当你得到的是滚动视图时很容易,因为你甚至不必滚动;你所要做的就是调整contentInset和scrollIndicatorInsets以摆脱键盘的方式,其余部分自动发生:

- (void) keyboardShow: (NSNotification*) n {
    self->_oldContentInset = self.scrollView.contentInset;
    self->_oldIndicatorInset = self.scrollView.scrollIndicatorInsets;
    self->_oldOffset = self.scrollView.contentOffset;
    NSDictionary* d = [n userInfo];
    CGRect r = [[d objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    r = [self.scrollView convertRect:r fromView:nil];
    CGRect f = self.fr.frame;
    CGFloat y =
        CGRectGetMaxY(f) + r.size.height -
            self.scrollView.bounds.size.height + 5;
    if (r.origin.y < CGRectGetMaxY(f))
        [self.scrollView setContentOffset:CGPointMake(0, y) animated:YES];
    UIEdgeInsets insets;
    insets = self.scrollView.contentInset;
    insets.bottom = r.size.height;
    self.scrollView.contentInset = insets;
    insets = self.scrollView.scrollIndicatorInsets;
    insets.bottom = r.size.height;
    self.scrollView.scrollIndicatorInsets = insets;
}

我在本书的这一部分中给出了一些不同的策略,包括代码:

http://www.apeth.com/iOSBook/ch23.html#_keyboard_covers_text_field

所有这些都得到可下载项目的支持,您可以在我的github网站上获取这些项目。