I would like to add a button and some other views below a UIWebView. When the keyboard opens, these views should smoothly animate up while the keyboard rises. The UIWebView should resize smoothly. I currently have the following:
No keyboard:
Keyboard:
It looks like it's working fine, but in reality, this is what it looks like in the middle of resizing:
The UIWebView's bottom jumps up immediately, the keyboard resizes smoothly, and the bottom views lag a little bit behind.
I have the following code:
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyboardWillChangeFrameNotification:)
name:UIKeyboardWillChangeFrameNotification object:nil];
}
- (void)handleKeyboardWillChangeFrameNotification:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (!self.is_keyboard_open) {
self.bottom_constraint_constant = self.bottomConstraint.constant;
self.bottomConstraint.constant = kbSize.height + self.bottomConstraint.constant;
} else {
self.bottomConstraint.constant = self.bottom_constraint_constant;
}
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
self.is_keyboard_open = !self.is_keyboard_open;
}
The bottom constraint is the constraint between the text and the bottom of the screen.
Another issue I have is that when the keyboard is toggled more than once, the UIWebView does not resize correctly when it is opened, causing a partial render, as well as a large gray box at the bottom (which I can scroll up and down along with rest of the content, which would fit normally if this gray box was not present), like so:
What can I do? Thank you for your help!
You should animate the constraint change. You have all the information necessary in the notification user info (UIKeyboardAnimationCurveUserInfoKey
, UIKeyboardAnimationDurationUserInfoKey
).
Your second issue is a problem with UIWebView
, I think. I've had this issue too. In iOS7, Apple seems to attempt setting a content inset for the webview scroll view, but sometimes it fails miserably. I ended up doing nasty tricks to prevent the webview from doing those.
Addendum
How to use the animation curve
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
// ... do stuff here
[UIView commitAnimations];
Webview tricks
Our webview use is even more complex because we use contentEditable=YES
to edit HTML content. What we did was taking full control of the internal webview subview.
Normally, the view hierarchy of a UIWebView
is:
UIWebView
UIScrollView
subclass
We ended up taking the private view and putting it inside our own scroll view which we can manage by ourselves. You need to update the content size as the private view grows or shrinks. We used key-value observation on the frame
property to listen to changes to the size. To have the correct content inset, we used the keyboard frame to determine how much the bottom content inset is.
I must postface this, and say that ideally, we should not do this. It's error prone. From experience, we know it works from iOS5 to iOS7.1. I cannot promise it will work on iOS8. But since there are bugs which cannot be resolved otherwise, this is the best solution we found.