0

Let's say that when the user presses a button a message needs to be shown and then a modal view controller is displayed. I would write something like that :

- (void)pickImageButtonPressed:(id)button {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert"
                                                    message:@"Some alert"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];

    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [[UIApplication sharedApplication].keyWindow.rootViewController
     presentModalViewController:picker animated:YES];
    [picker release];
}

With this code, the modal view controller is simply not displayed !

However, if I switch the two blocks of code (show modal first, then show the alert), the view controller is displayed modally and the alert shows up above it, exactly as I want.

My question is: why the alert prevents the modal view controller from being displayed ?

Please note that I do not want to wait for alert to be dismissed before calling presentModalViewController.


Update : I figured out that my production code was a bit more complicated than what I first put. I updated the example code and then finally found a simple example to reproduce the problem.

Note that in my production code, the popup is displayed from a place where I don't have any reference to a view controller, that's why I use [UIApplication sharedApplication].keyWindow.rootViewController instead of a direct reference to a view controller

David
  • 998
  • 7
  • 17
  • If "switch the two blocks" works "exactly as I want" why not just switch them. But it is because the `UIAlertView` is running on the main thread like a UI elements should do, but you have another UI element trying to run on the same thread so this is why it is delayed. You can't do two UI things on the main thread at the same time. And UI elements must run on the main thread. – Popeye Dec 13 '12 at 10:45
  • I tried your code and it's working as your were expecting – Inder Kumar Rathore Dec 13 '12 at 10:45
  • @Popeye Who told you that we can't do two UI things on main thread? there is no issue in doing so. – Inder Kumar Rathore Dec 13 '12 at 10:46
  • So the `UIImagePickerController` will not be able to run till the `UIAlertView` has been `release/Dismissed`. – Popeye Dec 13 '12 at 10:46
  • @Popeye: it's a bit complicated because in my application, the alert is called in a sub-sub function, so if I switch the "calls" I need to put an ugly warning comment so nobody switch the calls in the future. – David Dec 13 '12 at 10:47
  • Running at the exact same time. Such as a `UIAlertView` being present at the exact same time a `UIViewController` is changing. – Popeye Dec 13 '12 at 10:47
  • @InderKumarRathore I will see if I can find where it says, but it is in one of the Apple Docs. – Popeye Dec 13 '12 at 10:48
  • @InderKumarRathore : you're right, I'm sorry, this example works. My production code is more complicated than this, I'm trying to find the simplest code to reproduce the problem. If I don't, I'll try to delete this question. – David Dec 13 '12 at 10:54
  • @InderKumarRathore I can't seem to find it so I am probably wrong I was sure it was in some apple docs, but I stand with that the `UIAlertView` is blocking the `UIImagePickerController` from running cause `UIAlertView` is running on the main thread and it can run the next lot of code till it is dismissed. – Popeye Dec 13 '12 at 10:57
  • @InderKumarRathore : I updated the question with a more precise example of what is not working – David Dec 13 '12 at 12:24

1 Answers1

0

I finally found the answer. The issue really was on this line:

[[UIApplication sharedApplication].keyWindow.rootViewController
 presentModalViewController:picker animated:YES];

When an alert is displayed, [UIApplication sharedApplication].keyWindow.rootViewController is nil !. That's why the picker was never displayed. And that's why it worked when I switched the two blocks.

Now I need to find a way to get the most relevant view controller to present the picker modally...

David
  • 998
  • 7
  • 17
  • 1
    UIAlertView in fact takes over as the keyWindow when it is shown, that's why you get nil on rootViewController, because it's not your UIWindow anymore. If you have a UIWindow property stored on your app delegate you could use that one. – Rafael Nobre Aug 19 '13 at 20:02