How to make the view controller scroll to text field when keyboard appears

17,375

Solution 1

You can use a ScrollView.

Adding the scroll view

Drag an drop a scrollView onto your view controller, the same way you would with a text field and adjust the dimensions to suit your needs (it seems like you'd want it to fill the view controller.)

enter image description here

Then place the text fields into the scroll view. I think it's easiest to do using the document outline on the left. Drag the text fields onto the scroll view here, like in the picture.

enter image description here

Making the scroll view scroll when keyboard appears

Add this code to your view controller in viewDidLoad

//register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];

And add these methods to your view controller

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    [self.scrollView setContentOffset:CGPointMake(0, kbSize.height) animated:YES];
}
//called when the text field is being edited
- (IBAction)textFieldDidBeginEditing:(UITextField *)sender {
    sender.delegate = self;
}

The first two of these methods is called when the keyboard is shown. The second is called when you start to edit a text field.

Now go to your storyboard and attach actions of the text fields to the method that was just added. You can right click on the text field, select the appropriate action and drag it to the method.

Your should see something like this when you right click on your textfields.

enter image description here

Add this property to your view controller and right click drag from your scroll view to it. It allows your view controller to control the scroll view.

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

Like this:

enter image description here

Closing the keyboard

When the return button is pressed we want the keyboard to close.

In your view controller header make your view controller a UITextFieldDelegate Like this:

@interface ViewController : UIViewController <UITextFieldDelegate>

Add this code to your view controller in viewDidLoad

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

And add these methods to your view controller

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    return [textField resignFirstResponder];
}

The first method is called when the keyboard is closed. It returns the scroll view to its original position. The second method is called when you have finished editing a text field. It allows the keyboard to be dismissed when this happens.

More info

Here is more information on managing the keyboard.

And for reference here is my ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>

@end

and ViewController.m

#import "ViewController.h"

@interface ViewController () 
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    [self.scrollView setContentOffset:CGPointMake(0, kbSize.height) animated:YES];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
}
- (IBAction)textFieldDidBeginEditing:(UITextField *)sender {
    sender.delegate = self;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    return [textField resignFirstResponder];
}

@end

Solution 2

All the previous answers are great, but if you don't want to confuse yourself with code, use a control.

One that I love is: https://github.com/michaeltyson/TPKeyboardAvoiding (Cocoapods: pod 'TPKeyboardAvoiding')

All you have to do is embed your text fields into a UIScrollView (Editor/Embed In. Select your UITextFields first) then set that UIScrollView's class to TPKeyboardAvoidingScrollView.

Yes you should learn how to do it manually first, but after just use this if you'd like.

Solution 3

Select the text fields and go to the Editor menu, and choose Embed In -> Scroll View. This will automatically place a scroll view in your view hierarchy and move the text fields into it.

Also often when people want to have multiple text fields on screen and have them scroll, they will actually place them in a UITableView, where each cell has a text field in it. Usually this is with the grouped table view cell style. If you do it this way, the table view can handle automatically adjusting its size when the keyboard appears, so that you don't have to handle this yourself.

Share:
17,375
Exception
Author by

Exception

skype saad11842

Updated on July 23, 2022

Comments

  • Exception
    Exception almost 2 years

    I want to make my uiviewcontroller.xib scroll. My view controller has like 8 textfields. So my problem is when I want to write something in the 5th textfield and so on my keyboard covers the textfields. How can I get rid of this problem, and make my viewcontroller scroll?

    Please guide in detail because am new to iPhone development.

    Thanks in advance.

  • Gavin
    Gavin over 10 years
    The problem with this is you have to manually handle either adjusting the scroll area or resizing the scroll view when the virtual keyboard appears and disappears. Also you have to do extra work to make the text field scroll to be visible. If you use a UITableViewController and put the text fields in the table view cells, then some of this (not all) gets automatically handled for you. For example it automatically resizing the scrollable area when the virtual keyboard appears.
  • Connor
    Connor over 10 years
    That's true. Using a table view is probably best for the authors problem. I voted up your answer, but I'll leave this here (and expand it if needed) if the author still wants/ needs to use this method.
  • Exception
    Exception over 10 years
    I have done with selecting the text field and embed but textfield are still hiding behind the keyboard...
  • Exception
    Exception over 10 years
    @connor please proceed, Like if this is not solution to my problem it will be solution for someone else.
  • Connor
    Connor over 10 years
    This is a good solution to your question: stackoverflow.com/a/1127025/754604
  • Gavin
    Gavin over 10 years
    Try the approach I mention about using a UITableViewController. Otherwise, when using a UIScrollView you'll have to manually handle resizing it when the virtual keyboard shows and hides, which requires listening for those notifications, and so it can be a big hassle. The UITableViewController approach is much simpler.
  • Exception
    Exception over 10 years
    yes I know uitableview is an easy approach but there are particular cases where I can't.
  • Exception
    Exception over 10 years
    they way you answering is great and easy to understand for a beginner like me and it will be helpful for newcomers.
  • Exception
    Exception over 10 years
    Please add the rest of the steps It will be like some good tutorial trust me.
  • MarkP
    MarkP about 9 years
    @connor an absolutely awesome reply. Can I ask, would you mind adding in a Swift version of this?
  • Toad
    Toad almost 9 years
    You forgot to remove the notifications in the dealloc