Chris
Chris

Reputation: 40613

How to make a UITextView scroll all the way to the bottom when the keyboard is visible

I have an editable UITextView with a couple pages worth of text. When the user taps inside and it brings up the keyboard, it hides the bottom part of the text and you can not scroll to see it.

Is there some obvious/easy/standard way to deal with this? I assume its a common issue. I assume that you have to resize the text view when the keyboard is up, or something like that?

Also, when they tap on the text view in the bottom half of the page, how to make it automatically scroll so that the line they tapped on is visible when the keyboard appears? Or will this be automatically taken care of if i resize the text view when the keyboard appears.

Thanks a lot guys

Upvotes: 3

Views: 2925

Answers (2)

Karlis
Karlis

Reputation: 1910

This will nicely scroll your UITextView to the top of the keyboard when editing starts. This will also work if your UITextView have dynamic height (autogrow/autosize when typing). Tested in iOS 7.

Call your keyboard observer method and set UITextView delegate to current class:

- (void)viewDidLoad
{
    ...
    [self observeKeyboard];
    textView.delegate = (id)self;
}

Add keyboard observer for UIKeyboardDidShowNotification and UIKeyboardWillShowNotification:

- (void)observeKeyboard
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}

Get keyboard size:

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

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

When UITextView did begin editing or value has changed call scrollKeyboardToTextView:

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    [self scrollKeyboardToTextView:textView];
}

- (void)textViewDidChange:(UITextView *)textView
{
    [self scrollKeyboardToTextView:textView];
}

Scroll UITextView with animation to the top of the keyboard:

- (void)scrollKeyboardToTextView:(UITextView *)textView
{
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, _keyboardHeight, 0.0);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;

    CGRect aRect = self.view.frame;
    aRect.size.height -= _keyboardHeight;
    CGPoint origin = textView.frame.origin;
    origin.y -= self.scrollView.contentOffset.y;
    origin.y += textView.frame.size.height;

    CGPoint scrollPoint = CGPointMake(0.0, textView.frame.origin.y + textView.frame.size.height - (aRect.size.height));
    [self.scrollView setContentOffset:scrollPoint animated:YES];
}

Upvotes: 1

faroligo
faroligo

Reputation: 585

This has been discussed extensively here: How to make a UITextField move up when keyboard is present?

I personally have used Shiun's solution in the past and it works well.

UPDATE: If you don't want to use that method, a slightly simpler method is to resize your text field when the keyboard shows. It would be better to follow the instructions on the link I posted above as the KeyboardWillShow notification will give you access to the keyboard height.

First set the delegate of the UITextField = self. Then:

-(void)textFieldDidBeginEditing:(UITextField *)textField { // This is where the keyboard becomes visible
    textField.frame = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, textField.frame.size.width, textField.frame.size.height-100);
}

-(void)textFieldDidEndEditing:(UITextField *)textField { // This is where the keyboard hides itself
    textField.frame = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, textField.frame.size.width, textField.frame.size.height+100);
}

You can tweak the 100 depending on your orientation etc. If you wanted to add some animations you could do:

-(void)textFieldDidBeginEditing:(UITextField *)textField { // This is where the keyboard becomes visible
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:0.5];
        [UIView setAnimationBeginsFromCurrentState:YES];
        textField.frame = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, textField.frame.size.width, textField.frame.size.height-100);
        [UIView commitAnimations];
    }

    -(void)textFieldDidEndEditing:(UITextField *)textField { // This is where the keyboard hides itself 
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:0.5];
        [UIView setAnimationBeginsFromCurrentState:YES];
        textField.frame = CGRectMake(textField.frame.origin.x, textField.frame.origin.y, textField.frame.size.width, textField.frame.size.height+100);
        [UIView commitAnimations];
    }

Upvotes: 4

Related Questions