1

I am trying to make a UIScrollView scroll when the user starts editing a UITextField and the text field is hidden by the keyboard. I am using an example from the following thread.

How to make a UITextField move up when keyboard is present

I have four UITextFields in my view. When the keyboard is shown for the first time the view does not scroll automatically. If I click another text field with the keyboard shown, the UIScrollView scrolls as intended. Hiding the keyboard (by tapping the "Done" button) and tapping a UITextField again the same issue occurs: the UIScrollView does not scroll at first but when changing focus to another text field it scrolls perfectly.

Can anyone please help me?

In viewDidLoad I set the size of the scrollView

keyboardIsShown = NO;
CGSize scrollContentSize = CGSizeMake(320, 350);
self.scrollView.contentSize = scrollContentSize;

I register for the keyboard notifications in viewWillAppear

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:self.view.window];

Then I unregister in viewWillDisappear

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];

The following two methods are called by the notifications.

- (void)keyboardWillShow:(NSNotification *)n {
    if (keyboardIsShown) {
        return;
    }

    NSDictionary *userInfo = [n userInfo];

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

    CGRect viewFrame = self.scrollView.frame;
    viewFrame.size.height -= (keyboardSize.height - 50);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];

    [UIView setAnimationDuration:0.3];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = YES;
}

- (void)keyboardWillHide:(NSNotification *)n {
    NSDictionary *userInfo = [n userInfo];

    NSValue *boundsValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGSize keyboardSize = [boundsValue CGRectValue].size;

    CGRect viewFrame = self.scrollView.frame;
    viewFrame.size.height += (keyboardSize.height - 50);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];

    [UIView setAnimationDuration:0.3];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = NO;
}
Community
  • 1
  • 1
simonbs
  • 7,932
  • 13
  • 69
  • 115
  • Hey there, if you want to get the keyboard-height in your "keyboardWillHide:"-method, is the height of the keyboard 0? Did you set a breakpoint in your method, in order to see whether the program is going into that method or not? – Lepidopteron Apr 01 '11 at 08:53
  • The height of the keyboard in `keyboardWillHide` is 216. `keyboardWillShow` is called when the keyboard shows up for the first time and `keyboardWillHide` is correctly called when the keyboard is dismissed. – simonbs Apr 01 '11 at 09:00

1 Answers1

2

If you want to show the textfeild when keyboard is visible then use the code below. Don't go with the scrollview. If it is compulsory to use a scrollView then neglect this answer.



#define kOFFSET_FOR_KEYBOARD 280.0

- (void)keyboardWillHide:(NSNotification *)notif {
    [self setViewMoveUp:NO];
}


- (void)keyboardWillShow:(NSNotification *)notif{
    [self setViewMoveUp:YES];
}


- (void)textFieldDidBeginEditing:(UITextField *)textField {
    stayup = YES;
    [self setViewMoveUp:YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField {
    stayup = NO;
    [self setViewMoveUp:NO];
}

//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMoveUp:(BOOL)moveUp
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view
    [UIView setAnimationBeginsFromCurrentState:YES];

    CGRect rect = self.view.frame;
    if (moveUp)
    {
        // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
        // 2. increase the size of the view so that the area behind the keyboard is covered up.

        if (rect.origin.y == 0 ) {
            rect.origin.y -= kOFFSET_FOR_KEYBOARD;
            //rect.size.height += kOFFSET_FOR_KEYBOARD;
        }

    }
    else
    {
        if (stayup == NO) {
            rect.origin.y += kOFFSET_FOR_KEYBOARD;
            //rect.size.height -= kOFFSET_FOR_KEYBOARD;
        }
    }
    self.view.frame = rect; 
    [UIView commitAnimations];
}

Try this methods. Edit it according to your requirement.

Adarsh V C
  • 2,314
  • 1
  • 20
  • 37
  • This is very elegant and does work for my particular case but shouldn't it adjust where it scrolls to depending on where the UITextField is on the view? But thanks. It's great :-) – simonbs Apr 01 '11 at 10:24
  • but shouldn't it adjust where it scrolls to depending on where the UITextField is on the view? Re:- You should change #define kOFFSET_FOR_KEYBOARD 280.0 to a variable and play with that value through the methods. – Adarsh V C Apr 01 '11 at 11:47
  • I solved this by saving the selected text field as `textFieldSelected` in `- (void)textFieldDidBeginEditing:(UITextField *)textField` and then replace `kOFFSET_FOR_KEYBOARD` with `rect.origin.y -= textFieldSelected.frame.origin.y - kKeyboardOffset;` where my new `kKeyboardOffset` is the distance from the top of the view. Thank you very much! – simonbs Apr 01 '11 at 13:14