Question

I'm trying to display a UIAlertView with UIActivityIndicator after a user presses "log in" in a modal view controller. To log in, the credentials are sent to a server using sendAsynchronousRequest:queue:completionHandler: from the NSURLConnection class. My implementation is as follows:

UIAlertView * spinner = [[UIAlertView alloc] initWithTitle:@"Connecting to server..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[spinner show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.center = CGPointMake(spinner.bounds.size.width * 0.5f, spinner.bounds.size.height * 0.5f+5.0f);
[indicator startAnimating];
[spinner addSubview:indicator];
[indicator release];

[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * res, NSData * data, NSError * err) {
    [spinner dismissWithClickedButtonIndex:0 animated:YES];
    [spinner release];
    ...
}

This seems to work fine if the server can't be reached or the server is slow, but if the server replies immediatly, the spinner doesn't seem to be dismissed until after 3-5 seconds with the console logging

wait_fences: failed to receive reply: 10004003

I think this happens because I'm dismissing a modal view controller (the log in screen) while the UIAlertView is still showing but I'm not sure why this happens as it should normally be dismissed. Am I doing something wrong and what would be the correct way of doing this?

Was it helpful?

Solution

I have seen this log several times - it is always caused by an unexpected state in the internal animation framework or a collision between default view animations.

Possible reasons:

  1. Starting animations from inside viewDidLoad, viewWillAppear or similar method - before the view is actually displayed.
  2. Showing/Hiding a UIAlertView when another UIAlertView animation is still running. This includes showing an alert from alertView:didDismissWithButtonIndex:.
  3. Collision between modal view animation and alert animation.
  4. Collision between UINavigationController push/pop animation and alert animation.

Your case: You are probably hiding your alert even before it has been fully displayed and you get a collision between the two animations. The showing animation takes usually about 0.4 seconds but your response can arrive much earlier - triggering the hiding animation.

Possible solution:

  1. Trigger request when your animation ends (didPresentAlertView).
  2. Measure the duration of your connection and if it`s shorter than 0.4 secs, delay the hiding animation.

OTHER TIPS

You shouldn't do animations if the View Controller on which that animation is taking place did not appear. So no animations in viewDidLoad. Try in viewDidAppear. That's safer. Take a look here.

Hope this helps.

Cheers!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top