views:

1416

answers:

2

On an iPhone App, I've got a custom keyboard which works like the standard keyboard; it appears if a custom textfield becomes first responder and hides if the field resigns first responder. I'm also posting the Generic UIKeyboardWillShowNotification, UIKeyboardDidShowNotification and their hiding counterparts, like follows:

NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:5];
[userInfo setObject:[NSValue valueWithCGPoint:self.center]
             forKey:UIKeyboardCenterBeginUserInfoKey];
[userInfo setObject:[NSValue valueWithCGPoint:shownCenter]
             forKey:UIKeyboardCenterEndUserInfoKey];
[userInfo setObject:[NSValue valueWithCGRect:self.bounds]
             forKey:UIKeyboardBoundsUserInfoKey];
[userInfo setObject:[NSNumber numberWithInt:UIViewAnimationCurveEaseOut]
             forKey:UIKeyboardAnimationCurveUserInfoKey];
[userInfo setObject:[NSNumber numberWithDouble:thisAnimDuration]
             forKey:UIKeyboardAnimationDurationUserInfoKey];

[[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardWillShowNotification
                                                    object:nil
                                                  userInfo:userInfo];

This code is working and I use it in UIViewController subclasses.

Now since iPhone OS 3.0, UITableViewController automatically resizes its tableView when the system keyboards show and hide. I'm only now compiling against 3.0 and I thought that the controller should also resize the table if my custom keyboard appears, since I'm posting the same notification. However it doesn't. The table view controller is set as the delegate of the input fields.

Does anyone have an idea why this might be the case? Has anyone implemented something similar successfully?

I have standard input fields along the custom ones, so if the user changes the fields the standard keyboard hides and the custom one shows. It would be beneficial if the tableView didn't resize to full height and I didn't have to resize it back with a custom method.

A: 

I have done something similar. If I recall, I ended up just having the TableViewController subecibe to the notifications that either you send or the system sends, and then animate the change to the tableview's frame. Presumably there are doing something similar internally, but I think the end result just becomes two animation blocks wrapped around each other that both run when the system is posting the notifications, but the end result should be the same.

In your viewdidLoad:

[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(keyboardWillShow:) 
                                             name: UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(keyboardDidShowOrHide:) 
                                             name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(keyboardWillHide:) 
                                             name: UIKeyboardWillHidewNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(keyboardDidShowOrHide:) 
                                             name: UIKeyboardDidHideNotification object:nil];

and in the view controller:

-(void) keyboardWillShow:(id)sender {
  [UIView beginAnimations];
  [UIView setAnimationDuration:0.3];
  self.view.frame = //Your new size
}

-(void) keyboardDidShowOrHide:(id)sender {
  [UIView commitAnimations];
}

-(void) keyboardWillHide:(id)sender {
  [UIView beginAnimations];
  [UIView setAnimationDuration:0.3];
  self.view.frame = //Your old size
}
Brad Smith
That's how I'm doing it in my custom view controllers, I wanted to avoid this and plug into the standard mechanism of `UITableViewController`. BTW, is there a particular reason why you wait to commit the animations until keyboardDidShowOrHide:?
Pascal
Honestly, I am not sure why I waited, I vaguely remember there *was* a reason why at the time, but I wrote this code 2 years ago and whatever reason existed then may no longer be relevant. I have a sneaking suspicion that the standard mechanism that UITAbleViewController is using now, involves a method call to something undocumented which can always be a pain when working on this platform.
Brad Smith
Ah, yeah, that makes sense, OS 2.x required a lot of hacks here and there. :)
Pascal
A: 

Well there are a few possibilities that you poke around in. From your description, it seems that UITableView is not using the UIKeyboard Notifications.

But possibly, it is the UINavigationController that is responding to this notification (or UITabBarController).

You could override methods like setFrame: drawRect: and setNeedsDisplay in the tableview to see what is happening in the call stack. You may be able to figure out what is actually causing the tableview to redraw at the correct size.

But in all likelihood, just changing the size of the tableView yourself is the much easier solution. These suggestions are just for fun!

Corey Floyd
Yeah, I see this is what I have to do in order to find the solution (am currently on the road), and if I don't find something I can hook in I'll just solve it manually. Means I'll reward the bounty to you. :)
Pascal