views:

1001

answers:

4

I have a UIAlertView who's didDismissWithButtonIndex delegate method calls pops the view controller (same class, it's the alertview delegate and the viewcontroller) to return the user to the previous screen. The issue is that when you lock the phone before the [alert show]; is called, something is calling didDismissWithButtonIndex while the phone is locked. Since the response to that is to pop the view controller, which releases and deallocs it, I crash on the callback.

What is causing this phantom button press? Seems like a framework bug, but I hate jumping to that conclusion. I'm definitely not hitting the button, because I hit a breakpoint in my code right before it's displayed. Then I lock the phone. Then I continue. I see it do the show, return to the event loop, and then, while the phone is still locked, hit my breakpoint in didDismissWithButtonIndex. There are a few internet/forum postings about similar spurious delegate calls, but no concrete answers.

This is on the simulator, and the device, both OS 2.2 and OS 3.0. I'm assuming I'm missing something, but what?

Update: Yeah, I created a simple project with just two view controllers, where when the 2nd view controller displays it creates the alert, and shows it. Then I NSLog in the delegate method, and when the phone is locked, it fires once while locked, and then again when it's unlocked and the button is clicked...2 log messages. But when not locked, there's only one.

I guess I'll open an issue, but it seems awfully obvious to have survived this long without anyone complaining. :-) I'm going to try and work around it by making an isActive flag value when the willResignActive/didBecomeActive notifications arrive, and if the app isn't active skipping the delegate body.

Update I went ahead in July after I posted this and created radar 7097363 for this issue. There's been no response.

The workaround in practice works quite well, checking the active status when processing the delegate, and skipping the action if the the app is inactive.

A: 

Rob,

Are you able to duplicate the issue in a minimal project, say a nav controller and two view controllers, the second of which (pushed onto the navigation stack from the first) contains the UIAlertView and delegate. Seems that if it happens there, then it likely is a bug, otherwise, it's your code. ;-)

Matt Long
A: 

I'm experiencing the exact same problem.

When the device gets locked, the alertView delegate method didDismissWithButtonIndex is always called with the button index value set to 0 (this value is independent from the value of the cancelButtonIndex).

I'm working around this by doing nothing in the delegate method when the button index is 0. This might not be possible in your code.

Jean Regisser
A: 

Similar issue here: mine has nothing to do with the phone being locked, but I occasionally get an extra "didDismiss" call with a buttonIndex of 0 while the alert is actually still showing.

I'm sure I'm using UIAlertView incorrectly in a way I haven't been able to figure out (a thread issue, or showing the alert before the view is actually re-loaded after dismissing a different modalViewController, or ...?).

As a workaround, I tossed in this statement at the top of the "didDismiss" method, and it works (I suspect it would not work with "willDismiss" for obvious reasons):

- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{

    if (alertView.superview != nil)
    {
        // alert is still in some superview, so this is a false call to didDismiss
        return;
    }

    // the rest of your code

}
Jeff H
A: 

As a easier work around, only didDismissWithButtonIndex gets called in this way. Both clickedButtonAtIndex and willDismissWithButtonIndex do not get called in the locking situation.

In the normal flow of things you would get a "clickedButtonAtIndex" then a "willDismissWithButtonIndex" and finally "didDismissWithButtonIndex". When the phone is locked you only get "didDismissWithButtonIndex." So, if you use one of the other two instead of "didDismissWithButtonIndex" you won't be bothered during the lock.

honus