开发者

TableView frame not resizing properly when pushing a new view controller and the keyboard is hiding

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 c开发者_开发技巧onvertRect: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];   
}


Right before you push your view controller, find the first responder and call resign. Use the category from this SO post to see how to find the first responder recursively (not sure if you're already doing this).

- (void)tableView:(UITableView *)tableView 
          didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIView *fp = [[self view] findFirstResponder];

    [fp resignFirstResponder];

    // Push new view controller here.
    NextViewController *controller = [[NextViewController alloc] init];
    [[self navigationController] pushViewController:controller animated:YES];
    [controller release], controller = nil;
}

The other thing to keep in mind is that your table view is getting resized automatically because your root view controller is derived from UITableViewController (or so it seems). If you make your root view controller a regular UIViewController that contains a UITableView, you can manipulate the frame of the table view manually more easily--at least that's been my experience.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜