Search code examples
iosobjective-cuitextviewios9uikeyboard

UITextView disappears behind keyboard after typing a while


We're trying to support iOS 9 for a while yet... That's the only place this is happening...

I have a UITextView that occupies the entire view, which occupies the entire screen. I register to receive UIKeyboardWillShowNotification and UIKeyboardWillHideNotification. I get those just fine and adjust the height of my UITextView so that it is above the keyboard:

- (void) keyboardWillShow:(NSNotification *)aNotification 
    {
    CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect bounds = self.view.bounds;
    bounds.size.height = bounds.size.height - keyboardRect.size.height;
    self.textView.frame = bounds;
    }

Again, this works great. Now I type a few lines. For a while, the bottom line of text is kept above the keyboard automatically as I add more lines of text. But eventually, usually within just a few lines (maybe 4-5), the next line will go under the keyboard and I can continue typing lines under the keyboard. Eventually the lines I can still see above the keyboard will start scrolling up as I hit the bottom of the screen with the lines I'm typing behind the keyboard.

I am not getting the UIKeyboardWillHideNotification during this process, but it is almost behaving like I am -- that is, the size of my UITextView appears to return to its original size before the keyboard was shown.

All of this works fine in iOS 11. That is, as I type, the text scrolls up so the bottom line of text never goes behind the keyboard. It's just iOS 9. Anybody remember a known issue back in those days, and a work-around?


Solution

  • My best guess is that you're mixing Autolayout w/ Autoresizing and it seems to be picking the intended one in later iOS's but not in iOS 9.

    A quick sample using your code + auto layout constraints in the storyboard resulted in what I believe to be the behavior you're seeing in older iOS's (iOS 9.3 Simulator shown below):

    AutoResizing+AutoLayout_iOS9

    If I roll with a pure auto layout approach (i.e. IBOutlet the textView's bottom constraint and adjust the constant for that programmatically in keyboardWillShow) then it results in the correct behavior on iOS 9 (no setFrame call):

    Pure_AutoLayout_iOS9

    @property (strong, nullable) IBOutlet NSLayoutConstraint *textViewBottomConstraint;
    
    ...
    
    - (void)keyboardWillShow:(NSNotification *)aNotification {
        CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
        self.textViewBottomConstraint.constant = -keyboardRect.size.height;
    }