Scrolling UITextField into view when keyboard is shown

筅森魡賤 提交于 2019-12-08 09:39:11

问题


I'm writing an app targeting iOS 6.1. I'm trying to follow this Apple doc on how to scroll a UITextField into view if it is obscured by the keyboard. The problem is that Apple's documented algorithm for calculating the scroll point doesn't work so well. My algorithm for calculating the scroll point works only slightly better, but is off by 70 pixels. What is the correct way to calculate the scroll point?

Below you can see, from left to right, my view before the keyboard is shown, my view after scrolling using Apple's algorithm to calculate the scroll point, and my view after scrolling using my algorithm to calculate the scroll point. (Each square in that grid is 25 pixels by 25 pixels.)

And here is the code I am using. Note the #if APPLE_WAY block.

- (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];
    }
}

回答1:


You simply need to set the offset to the height of the keyboard:

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

hope this helps




回答2:


There are a few ways to do this. Given your situation, I would do something like this:

- (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];
    }
}

Then, in your viewDidLoad method:

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

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



回答3:


It's easy when what you've got is a scroll view, because you don't even have to scroll; all you have to do is adjust the contentInset and scrollIndicatorInsets to get out of the keyboard's way, and the rest happens automatically:

- (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;
}

I give a bunch of different strategies, with code, in this section of my book:

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

All of that is backed by downloadable projects that you can grab at my github site.



来源:https://stackoverflow.com/questions/15802015/scrolling-uitextfield-into-view-when-keyboard-is-shown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!