views:

420

answers:

3

When my iPhone app starts up, the main screen has a keyboard. Currently the keyboard rises as soon as the rest of the interface is displayed and this is visually distracting.

How can I have the view display with the keyboard already up?

Since I am already faking some of the rest of the screen during startup so that the user sees what they last were doing, I thought that I could fake the keyboard as well. But if the motion is there when the real keyboard appears, I've lost the effect. The keyboard is, as far as I know, on a separate window, not just a separate view, so I can't overlay it with my own image.

Is there a way to either overlay the keyboard withy my own image as it appears, or not show the keyboard until it is all the way up, or make its animation instant?

A: 

In viewWillAppear:, ensure the view is loaded (via self.view) and set the first responder to the correct field. This will display the keyboard fully when the view is actually displayed instead of animating it in.

For example:

- (void) viewWillAppear: (BOOL) animated {
  [super viewWillAppear:animated];

  NSString *storedID = [[NSUserDefaults standardUserDefaults] stringForKey:@"storedID"];
  if ([storedID length] > 0) {
    idField.text = storedEmail;
    [passwordField becomeFirstResponder];
  } else {
    [idField becomeFirstResponder];
  }
}
dmercredi
I was doing that in viewDidAppear and moved the code to viewWillAppear. However I get the same behavior as before. [super viewWillAppear:NO] doesn't have an effect either
Steve Weller
I do what you do in a modal view controller and it does work, so I know it can be done. So maybe the answer is to have a dummy view controller and then add a modal view controller on top of it and do the transition without animation.
Steve Weller
Tried using an intermediate view controller: no luck.If a view controller is added modally there is a choice of animation or not. If YES then the whole view comes up from the bottom with the keyboard in place. if NO, then the view appears instantaneously, but the keyboard still follows.
Steve Weller
Can you post some code? I've used this technique for both modal view controllers and within a navigation controller and it's worked fine for both. How/when is your text input field instantiated? Note that the view might not be created yet when viewWillAppear: is called so if you create the fields in viewDidLoad or if they're loaded from a resource they might be nil. [self view] will force the view to be created.
dmercredi
A: 

Not an answer, but here is some code.

I set the font for my UITextView in viewDidLoad. The view is instantiated by the NIB and the outlet is correctly set up.

-(void)viewWillAppear:(BOOL)animated;
{
[super viewWillAppear:animated];

// Start with the text from the currently edited message
NSString *startString = self.messageManager.editingMessage.text;
// start string processing omitted
self.editingMessageEditingView.text = startString;

if([self showingMessageList]) {
 [self.editingMessageEditingView resignFirstResponder];
} else {
#if DEFAULT_SCREEN==1
 [[self.tools.items objectAtIndex:kPVToolBarItemDelete] setEnabled:NO];
 [[self.tools.items objectAtIndex:kPVToolBarItemSendLater] setEnabled:NO];
#else
 [self.editingMessageEditingView becomeFirstResponder];
#endif
}
Steve Weller
+5  A: 

My original answer has the keyboard animate in along with the view controller if it's an animated transition (i.e. pushing a view controller or presenting a modal controller with animated: YES). However, the keyboard still animates in if the new view controller is displayed without an animated transition, so it doesn't solve your problem.

Here's another approach that worked in my testing. Try disabling animations while you're displaying the controller + keyboard.

[UIWindow beginAnimations: nil context: NULL];
[UIWindow setAnimationsEnabled: NO];

RestoredController *controller = [[[RestoredController alloc] init] autorelease];
[self.navigationController pushViewController: controller animated: NO];

[UIWindow commitAnimations];

You'll still need to make field the first responder in viewWillAppear: or viewDidAppear:

dmercredi
Thanks, this now works. [UIWindow beginAnimations: nil context: NULL]; [UIWindow setAnimationsEnabled: NO]; [[[window subviews] objectAtIndex:0] removeFromSuperview]; // Get rid of the fake screen [window addSubview:mainController.view]; // Add the real one [UIWindow commitAnimations];I just have to adjust my fake screen to include the keyboard image now and I will be done.
Steve Weller
Rats. No formatting in comments?
Steve Weller