The following code fixes a problem in the Jay answer , which assumes that UIKeyboardWillShowNotification will not start again when the keyboard is already present.
When typing with a Japanese / Chinese keyboard, iOS launches an additional UIKeyboardWillShowNotification with a new keyboard frame, even if the keyboard is already present, which leads to the fact that the height of self.textView reduced a second time in the source code.
This reduces self.textView almost zero. After that, it becomes impossible to repair this problem, since we expect only one UIKeyboardWillHideNotification at the next keyboard dismissal.
Instead of subtracting / adding height in self.textView depending on whether the keyboard is displayed or hidden, as in the source code, the following code simply calculates the maximum possible height for self.textView after subtracting the height of the keyboard on the screen.
It is assumed that self.textView should fill the entire view controller view, and there is no other self.textView view that should be visible.
- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif { NSDictionary* userInfo = [notif userInfo]; NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardFrameInWindowsCoordinates; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates]; [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates withAnimationDuration:animationDuration animationCurve:animationCurve]; } - (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates withAnimationDuration:(NSTimeInterval)duration animationCurve:(UIViewAnimationCurve)curve { CGRect fullFrame = self.view.frame; CGRect keyboardFrameInViewCoordinates = [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];
Also, be sure to register keyboard notifications in viewDidLoad:
- (void)viewDidLoad { [super viewDidLoad]; NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil]; }
About splitting resize code into two parts
The reason that the textView resizing code is split into two parts ( resizeTextViewWithKeyboardNotification: and resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: is to fix another problem when the keyboard is saved by pressing from one view controller to another (see How to determine iOS keyboard when it stays between controllers? ).
Since the keyboard is already present before pressing the view controller, there are no additional keyboard notifications generated by iOS, and therefore there is no way to resize the textView based on these keyboard notifications.
The above code (as well as the source code) that resizes self.textView will only work when the keyboard is displayed after the image has been loaded.
My solution is to create a singleton that stores the last coordinates of the keyboard, and in - viewDidAppear: viewController will call:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Resize the view if there any keyboard presence before this // Only call in viewDidAppear as we are unable to convertRect properly // before view is shown [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame] withAnimationDuration:0 animationCurve:0]; }
UASKeyboard is my singleton. Ideally, we should call it in - viewWillAppear: however, in my experience (at least on iOS 6), the convertRect:fromView: method that we need to use in resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: incorrectly converts the keyboard frame to coordinates The view in front of the view is fully visible.