Hi,
I must be missing something fundamental here. I have a UITableView inside of a NavigationViewController. When a table row is selected in the UITableView (using tableView:didSelectRowAtIndexPath:) I call pushViewController to display a different view controller. The new view controller appears correctly, but when I pop that view controller and return the UITableView is resized as if the keyboard was being displayed. I need to find a way to have the keyboard hide before I push the view controller so that the frame is restored correctly. If I comment out the code to push the view controller then the keyboard hides correctly and the frame resizes correctly.
The code I use to show the keyboard is as follows:
- (void) keyboardDidShowNotification:(NSNotification *)inNotification {
NSLog(@"Keyboard Show");
if (keyboardVisible) return;
// We now resize the view accordingly to accomodate the keyboard being visible
keyboardVisible = YES;
CGRect bounds = [[[inNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
bounds = [self.view convertRect:bounds fromView:nil];
CGRect tableFrame = tableViewNewEntry.frame;
tableFrame.size.height -= bounds.size.height; // subtract the keyboard height
if (self.tabBarController != nil) {
tableFrame.size.height += 48; // add the tab bar height
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(shrinkDidEnd:finished:contextInfo:)];
tableViewNewEntry.frame = tableFrame;
[UIView commitAnimations];
}
The keyboard is hidden using:
- (void) keyboardWillHideNotification:(NSNotification *)inNotification {
if (!keyboardVisible) return;
NSLog(@"Keyboard Hide");
keyboardVisible = FALSE;
CGRect bounds = [[[inNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
bounds = [self.view convertRect:bounds fromView:nil];
CGRect tableFrame = tableViewNewEntry.frame;
tableFrame.size.height += bounds.size.height; // add the keyboard height
if (self.tabBarController != nil) {
tableFrame.size.height -= 48; // subtract the tab bar height
}
tableViewNewEntry.frame = tableFrame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(_shrinkDidEnd:finished:contextInfo:)];
tableViewNewEntry.frame = tableFrame;
[UIView commitAnimations];
[tableViewNewEntry scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
NSLog(@"Keyboard Hide Finished");
}
I trigger the keyboard being hidden by resigning first responser for any control that is the first responder in ViewWillDisappear. I have added NSLog statements and see things happening in the log file as follows:
Show Keyboard
ViewWillDisappear: Hiding Keyboard
Hide Keyboard
Keyboard Hide Finished
PushViewController (an NSLog entry at the point I push the new view controller)
From this trace, I can see things happening in the right order, but It seems like when the view controller is pushed that the keyboard hide code does not execute properly.
Any ideas would be really appreciated. I have been banging my head against the keyboard for a while trying to find out what I am doing wrong.
-- Added didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0: // Required Info
// removed to simplify
case 1: // Optional Info
switch (indexPath.row) {
case 0:
[self showTextDetailPicker: @"Enter a description"
tag: tDescriptionPicker
sourceTarget: self.newRecord
fieldSource: @selector(description)];
break;
default:
break;
}
break;
default:
break;
}
}
- (void) showTextDetailPicker: (NSString*) titleText tag:(int)tagID sourceTarget:(NSObject*)target fieldSource:(SEL)selector{
FieldEditorViewController *fe = [[FieldEditorViewController alloc] init];
fe.titleText = titleText;
fe.fieldText = [target performSelector: selector];
fe.tag = tagID;
// Replace default back button with one that just says 'Back'
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc]
initWithTitle:@"Back"
style:UIButtonTypeInfoLight
target:nil action:nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];
[fe setDelegate: self];
[self.navigationController pushViewController:fe animated:YES];
[fe release];
}