1

I have a question concerning "Moving Content That Is Located Under the Keyboard".

I have a simple "sign in" view with 2 UITextFields (username and password) and a sign in button. When the user taps on one of those text fields the keyboard appears and obscurs the sign in button and the password text field. So I implemented the solution proposed by Apple and one other (see links below) :

https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

http://ios-blog.co.uk/tutorials/how-to-make-uitextfield-move-up-when-keyboard-is-present/

But the problem is that the keyboard moves first and it's only when the keyboard has finished to move that the 2 UITextFields and the sign in button move. Thus it's not the best solution for User Experience... Do you know I can move the keyboard and the 2 UITextFields at the same time ? Like on the iOS Facebook login page.

Thanks !

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Michel
  • 100
  • 10

3 Answers3

1

Just shift content when UIKeyboardWillShowNotification is received. Instead of UIKeyboardDidShowNotification.

UPDATE

Also if you need to add animation you could use userInfo from keyboard notification to fetch keyboard height, speed of emerging and animation curve.

So this code should react for UIKeyboardWillShowNotification:

[UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] delay:0.0f options:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue] animations:^{
    // TODO: shift content here
} completion:nil];

Also you need something similar for UIKeyboardWillHideNotification. Difference would be just direction of shifting inside animations block.

Artem Stepanenko
  • 3,423
  • 6
  • 29
  • 51
1

In this case, you should intercept the UIKeyboardWillShowNotification notification and offset your content animately with an animation block.

[UIView animateWithDuration:0.5 animations:^{
    // your own animation code 
    // ...
} completion:nil];`

The same is for the UIKeyboardWillHideNotification notification.

Of course, if you are scrolling the content with an already-animated method, you can just put that without the need of an animation block.

Guido Lodetti
  • 739
  • 2
  • 8
  • 20
1

Well, you can do this in 2 ways: the easy way, and the hard way.

Easy way: Instead of a ViewController, use a TableViewController and create custom cells that contain the text fields. The TableViewController will take care of moving the view up for you when the keyboard goes up. Then all you have to worry about is to dismiss the keyboard whenever you want the keyboard to go away.

The hard way: Use a ViewController. In order for this to work you need to have 2 notifications, like this ones (place this inside your viewDidLoad method):

        // Keyboard notifications so things can move up when the keyboard shows up
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

Then you need to create the 2 methods you're calling in the NotificationCenter, to actually perform the movement of the screen:

- (void) keyboardWillShow: (NSNotification*) aNotification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    CGRect rect = [[self view] bounds];
    rect.origin.y -= 150;
    [[self view] setFrame: rect];
    [UIView commitAnimations];
}

// Call this to make the keyboard move everything down
- (void) keyboardWillHide: (NSNotification*) aNotification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    CGRect rect = [[self view] frame];
    if (rect.origin.y == -150)
    {
        rect.origin.y += 150;
    }
    [[self view] setFrame: rect];
    [UIView commitAnimations];
}

In this code, the value of 150 is an arbitrary number of points that the keyboard will go up/down. You can change it or do some fancy calculation to get a percentage of the screen regardless of the screen size.

Hope it helps!

TooManyEduardos
  • 4,206
  • 7
  • 35
  • 66
  • Your solution is fluid and easy to implement, but everything moves up : images, labels... It's a good solution for simple "sign in" view, but if you have a background image or labels, they will also move up – Michel Jun 25 '14 at 17:04
  • You can solve that by placing the buttons inside a UIView of their own. That way you have the background inside a UIView, and inside that main UIView you have another UIView. In the code, change the way you call the line of [[self view]setFrame:rect]; for whatever view you want to move up/down – TooManyEduardos Jun 25 '14 at 17:13
  • Thanks for your idea ! I was just thinking about a solution like this ! I implemented your solution and it works ! Many thanks ! – Michel Jun 25 '14 at 17:42