Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resizing a UIScrollView with Animation block moves origin

i'm in the process of scrolling a UIScrollView up if the keyboard will hide a UITextField. i reduce the UIScrollView's height if it will be covered up which works fine. but when i try to grow the UIScrollView's heigh (back to original size), the whole UIScrollView moves up the and then animates down to the original size and location. the origin moves up by X amount and moves down to where it should be instead of the height of the view expanding down.

- (void)keyboardWillShow:(NSNotification *)n
{
    keyboardMove = self.rightScrollView.frame;
    offsetMove = self.rightScrollView.contentOffset;

    NSDictionary* userInfo = [n userInfo];

    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    [UIView animateWithDuration:.25
                          delay:0
                        options:(UIViewAnimationOptionAllowUserInteraction)
                     animations:^
                     {
                         self.rightScrollView.frame = CGRectMake(self.rightScrollView.frame.origin.x, self.rightScrollView.frame.origin.y, self.rightScrollView.frame.size.width, (self.view.frame.size.height - (self.rightScrollView.frame.origin.y + keyboardSize.height)));
                     }
                     completion:nil];

    if ((activeTextField.frame.origin.y + activeTextField.frame.size.height) > self.rightScrollView.frame.size.height)
    {        
        float contentOffsetMove = (self.rightScrollView.contentOffset.y + (activeTextField.frame.origin.y - self.rightScrollView.frame.size.height) + activeTextField.frame.size.height + 10);

        self.rightScrollView.contentOffset = CGPointMake(self.rightScrollView.contentOffset.x, contentOffsetMove);
    }
}

- (void)keyboardWillHide:(NSNotification *)n
{
    if ((activeTextField.frame.origin.y + activeTextField.frame.size.height) > self.rightScrollView.frame.size.height)
    {
        [UIView animateWithDuration:.25
                              delay:0
                            options:(UIViewAnimationOptionAllowUserInteraction)
                         animations:^{
                             [self.rightScrollView setContentOffset:offsetMove animated:YES];

                             self.rightScrollView.frame = keyboardMove;
                         }
                         completion:nil];

    }
    else
    {
        [UIView animateWithDuration:.25
                              delay:0
                            options:(UIViewAnimationOptionAllowUserInteraction)
                         animations:^{
                             self.rightScrollView.frame = keyboardMove;
                         }
                         completion:nil];
    }
}

so, when keyboard hides, self.rightScrollView.origin moves up X points and then animates to the location is should be. i need the origin to stay put and the height become more (grows downwards).

any ideas why its behaving goofy?

like image 860
Padin215 Avatar asked Jan 17 '12 21:01

Padin215


2 Answers

I don't know if you're still interested in the answer since I see the last activity here was a year ago, but today I stumbled across the exact same problem in iOS 6 and decided to share my solution with anyone still interested.

I noticed the offset by which the UIScrollView moves up is half the size of the keyboard's height, but only if the UIScrollView's content is offset. So my workaround was to move the UIScrollView DOWN with the exact same amount just before the animation, if the UIScrollView's content's offset is greater than 0. This works fine on both iPhone 4 (3.5" display) and iPhone 5 (4" display) for now, but I don't know what will happen if Apple decides to fix this, in case it really is a UIKit bug.

Anyway, here's my code for clarity's sake:

- (void)keyboardWillHide:(NSNotification *)notification
{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    if (self.scrollView.contentOffset.y > 0) {
        CGRect f = CGRectMake(0, keyboardSize.height / 2, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
        self.scrollView.frame = f;
    }

    [UIView animateWithDuration:0.25 animations:^{
        self.scrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }];
}
like image 135
Zoltan Vari Avatar answered Oct 12 '22 09:10

Zoltan Vari


I believe this is potentially a bug in UIKit but the way around this is to work with the scrollView's contentInset instead of adjusting the frame. So:

Instead of

self.rightScrollView.frame = CGRectMake(self.rightScrollView.frame.origin.x,
                                        self.rightScrollView.frame.origin.y,
                                        self.rightScrollView.frame.size.width,
                                        (self.view.frame.size.height - (self.rightScrollView.frame.origin.y + keyboardSize.height)));

do

self.rightScrollView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
like image 44
Paul.s Avatar answered Oct 12 '22 07:10

Paul.s