3

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

Chris
  • 39,719
  • 45
  • 189
  • 235

2 Answers2

4

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];
    }
Community
  • 1
  • 1
faroligo
  • 585
  • 2
  • 13
  • I had a read of that page before, and wasn't sure if it applied, as he had a scroll view with a bunch of text fields. I only have a UITextView as the main view in my nib. Plus those solutions seemed overly complex, is there some simple setting we're missing here? – Chris Nov 23 '10 at 23:41
  • In your case, to ensure it stays visible, you are going to need to resize your text field when the keyboard shows and resize it again when it hides. See the code in my update and see if that helps you. – faroligo Nov 23 '10 at 23:55
  • 1
    @Chris : A UITextView is a scrollview, so the same techniques apply. There is no simple "magic do what I mean" setting for you. – hotpaw2 Nov 23 '10 at 23:58
1

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];
}
Karlis
  • 1,870
  • 1
  • 15
  • 15