I have a UIViewController
that contains a UITableView
with custom cells, inside the cell are UILabels
, a couple of uneditable UI
I've always used a two fold solution for this.
To do this, I register keyboard show/hide events and act accordingly when they get called.
- (void)keyboardWillShow:(NSNotification *)note {
[self updateForKeyboardShowHide:note appearing:YES];
}
- (void)keyboardWillHide:(NSNotification *)note {
[self updateForKeyboardShowHide:note appearing:NO];
}
- (void)updateForKeyboardShowHide:(NSNotification *)note appearing:(BOOL)isAppearing {
// ignore notifications if our view isn't attached to the window
if (self.view.window == nil)
return;
CGFloat directionalModifier = isAppearing?-1:1;
CGRect keyboardBounds = [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat animationDuration = [[note.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
// figure out table re-size based on keyboard
CGFloat keyboardHeight;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation))
keyboardHeight = keyboardBounds.size.height;
else
keyboardHeight = keyboardBounds.size.width;
[UIView animateWithDuration:animationDuration animations:^{
// resize table
CGRect newFrame = table.frame;
newFrame.size.height += [self calculateKeyboardOffsetWithHeight:keyboardHeight] * directionalModifier;
table.frame = newFrame;
} completion:^(BOOL finished){
// scroll to selected cell
if (isAppearing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textFieldInEdit.tag inSection:0];
[table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}];
}
- (CGFloat)calulateKeyboardOffsetWithHeight:(CGFloat)keyboardHeight {
// This depends on the size and position of your table.
// If your table happen to go all the way to the bottom of
// the screen, you'll needs to adjust it's size by the whole keyboard height.
// You might as well ditch this method and inline the value.
return keyboardHeight;
// My table did not go to the bottom of the screen and the position was
// change dynamically so and there was long boring calculation I needed to
// do to figure out how much my table needed to shrink/grow.
}