Skip to content

Instantly share code, notes, and snippets.

@janodev
Created October 16, 2011 08:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janodev/1290641 to your computer and use it in GitHub Desktop.
Save janodev/1290641 to your computer and use it in GitHub Desktop.
Prevent the keyboard covering the view
/**
* Register keyboard notifications.
*/
-(void) registerKeyboardNotifications {
trace(@"register keyboard notifications");
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardWillShowNotification object:nil];
[center addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
}
/**
* Unregister keyboard notifications.
*/
-(void) unregisterKeyboardNotifications {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
/**
* Scrolls up the view to prevent the keyboard covering the view.
*
* This adds a bottom inset whose height is equal to that of the keyboard,
* and then scrolls the view so that the keyboard covers the inset, and not the view.
*/
- (void)keyboardDidShow:(NSNotification *)notification
{
CGFloat insetHeight = 0;
{
// the keyboard is mounted on the window object
AppDelegate *delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
UIWindow *window = delegate.window;
// UIKeyboardFrameEndUserInfoKey is key for the keyboard frame in screen coordinates
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
// convert scrollview frame to window coordinates to account for rotations
CGRect ownFrame = [window convertRect:self.scrollView.frame fromView:self.scrollView.superview];
// calculate the area covered by the keyboard
CGRect coveredFrame = CGRectIntersection(ownFrame, keyboardFrame);
// convert back in case screen is rotated
coveredFrame = [window convertRect:coveredFrame toView:self.scrollView.superview];
// Now coveredFrame gives us exactly the area of our view that is covered,
// and thus the hight is also the bottom inset we need to apply.
insetHeight = coveredFrame.size.height;
}
// set inset
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, insetHeight, 0);
self.scrollView.scrollIndicatorInsets = self.scrollView.contentInset;
// scroll to bottom minus the inset
CGFloat offset = [self.scrollView contentSize].height - self.scrollView.contentInset.bottom;
CGPoint bottomOffset = CGPointMake(0, offset);
[self.scrollView setContentOffset:bottomOffset animated:YES];
}
/**
* Removes the inset previously applied.
*/
- (void)keyboardWillHide:(NSNotification *)notification {
// read the animation settings of the keyboard
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
NSDictionary* userInfo = [notification userInfo];
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
// Remove the inset using the animation settings of the keyboard.
// This has the effect of moving the view down in sync with the keyboard.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
self.scrollView.scrollIndicatorInsets = self.scrollView.contentInset;
[UIView commitAnimations];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment