views:

5077

answers:

8

I get this cryptic error the first time (and only the first time) my view is loaded due to the following line of code:

- (void)viewWillAppear:(BOOL)animated
{
    [textField becomeFirstResponder];
}

There is a noticeable (~3 – 4 second, even on the simulator) delay due to this that makes my app feel unresponsive. Does anyone know how to fix this? I can't find any documentation on it on Apple's site, or any solutions here or on Google.

Strangely, the opposite situation happens if I put the line in -viewDidAppear: instead of -viewWillAppear:; that is, instead of printing the error only the first time the keyboard is shown and never again, the error is not printed the first time but every time after. This is causing a major headache for me.

+1  A: 

See here for more info: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait%5Ffences-failed-receive-reply-10004003-a.html

Your problem is related.

Andrew Johnson
Thanks for the help, but unfortunately I can't find a solution for my problem on that page. "It seems to occur when a subview (eg. UIAlertView) is created prior to its parent/super view." This shouldn't be happening in the above code, right?
Michael
A: 

Is the Text Field contained within that view, or within something else? You can only send the 'becomeFirstRepsonder' to something that is contained directly within that view. If it's stored in some other widget component, you shouldn't set the first responder status in this widget, but rather in the widget that's being created. For example, if you're adding the text field to an alert view, because the show happens asynchronously, it might not be up by the time you call the becomeFirstResponder. (Ideally, you'd have your own alert view class and define the text field within that, and when that view receives the viewDidAppear, you'd set the textfield as first responder at that point.)

AlBlue
+7  A: 

Override -viewDidAppear:, not -viewWillAppear, and make sure to call [super viewDidAppear:]. You should not perform animations when you are not on screen ("will appear"). And the -viewDidAppear: docs explain that you must call super because they have their own things to do.

Rob Napier
This is not as responsive as I'd like (there's still a slight delay showing the keyboard each time), but it seems to do the trick.
Michael
I know the lag you're talking about. I've seen it in a lot of apps. You might try calling -becomeFirstResponder before (rather than after) calling -[super viewDidAppear:] if you're not already. This may have no impact, but might get the animation started in the same event loop rather than the next one. I haven't experimented with this yet to confirm.
Rob Napier
This doesn't fix the problem. If you throw up a UIAlertSheet in viewDidAppear, after calling [super viewDidAppear:animated], you end up with the same message, every time. if, however, you throw it up afterwards, say in response to an ibaction, no problem. so performWithSelector is probably the way to fix, or you could ignore the message, either way this appears to be an SDK bug, not a problem with your code.
Billy Gray
@Billy, throwing up a UIAlertSheet before animations are done would likely cause the same problem. In any case you're putting up a sheet inside of viewDidAppear is probably too early and you probably should use performSelector:afterDelay: to push the UIAlertSheet to the next loop. That's not a bug in the SDK, though the details here are poorly documented. Performing animations in -viewWillAppear was the bug in the original code. In either case, you shouldn't ignore the message. It can lead to odd visual artifacts (a strange sideways sliding of the animation).
Rob Napier
+3  A: 

I was getting a similar error when quickly:

  1. Dismissing a modal view
  2. Updating the main view
  3. Presenting a new modal view

I noticed I was only getting it in the simulator and not on the device. Additionally, I was getting caught in an infinite loop.

My solution was to delay the presenting of the new modal view. It seems that quickly updating the view hierarchy caused some sot of race condition in Apple's code.

With that in mind, try this:

     - (void)viewDidAppear:(BOOL)animated{

            [super viewDidAppear:animated];
            [textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
  }

You may be having issues presenting the keyboard for a UITextField that ins't yet on screen. This may be causing problems similar to mine.

Also, you pause giving the hierarchy time to update before presenting the keyboard, just in case.

Hope this helps.

Corey Floyd
To the issues you were having with modals, did you wait for the modal to finish dismissing before presenting the new modal? Rather than waiting an arbitrary period of time and hoping it's completed, you can know by overriding -viewDidDisappear in the modalViewController. That can call back to the modal's -parentViewController, or could post a notification. The key is to understand that asking something to dismiss does not mean it is gone yet, and you shouldn't animate things on top of each other in general. -viewWill/DidDisappear is generally your best way to know for sure when things happen.
Rob Napier
The first modal view was the photo picker, and I handles everything within the photo picker call back method. Your right, I should have place the code to launch the next modal view within viewDdiAppear. that is a better solution and would most likely fix the issue regardless of platform.
Corey Floyd
Thanks, this helped me.
kukudas
A: 

overide viewDidappear not viewWillAppear:

-(void) viewDidAppear:(BOOL) animated { [super viewDidAppear:animated]; [myTextField becomeFirstResponder]; }

Manu
+2  A: 

you have done [textfield becomeFirstResponder];

and after you get the value from textfield in your code make [textfield resignFirstResponder]; that will help you i think

Gani
+1  A: 

If you're running the current iPhone Simulator 4.0, this error message appears frequently when rotating the screen (or when animating after rotating the screen) accompanied by 1-2 second lag in the animations.

It is a bug in this version of the Simulator and should be fixed soon.

Matt Gallagher
thanks for info about iOS4 simulator bug. for the same project, the `wait_fences` message didn't show up in the 3.1 simulator
ohho
+3  A: 

After trying everything I could find on Google and none of it working, this is what solved the problem for me. The key is that I'm doing this stuff in the willDismissWithButtonIndex delegate method. Before I was doing it elsewhere.

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [myTextField resignFirstResponder];
    [myTextField removeFromSuperview];  
    [myTextField release];  
}
warehouselabs
thanks......it solved my problem
Sijo