Search code examples
iosuiimagepickercontrollermodalviewcontrollerpresentviewcontroller

iOS - Is it possible to present a modal view controller from a modally presented view controller?


I'm working on an app that presents an "edit profile" screen. Then from that screen I want to be able to present another modal view controller, UIImagePickerController. However, I'm unable to do so and continue to receive the following error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modal view controller on itself. Presenting controller is UIImagePickerController: 0x13d077000.'

In my app, on my profile screen, I have the upper right bar button item present an "edit profile" screen modally like so:

//  MyProfileViewController.m
// ...

- (void)rightBarButtonItemTapped:(id)sender
{
    EditMyProfileViewController *editMyProfileVC = [[EditMyProfileViewController alloc] init];
    editMyProfileVC.delegate = self;
    UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:editMyProfileVC];
    navVC.navigationBar.translucent = NO;
    [self presentViewController:navVC animated:YES completion:^{}];
}

Then, from within the context of the modally presented "edit profile" screen, I want to be able to modally present UIImagePickerController. I try to do this like so:

//  EditMyProfileViewController.m
// ...

#pragma mark - UIActionSheetDelegate

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if ([actionSheet isEqual:self.profilePicActionSheet])
    {
        if (buttonIndex == 0) // Camera
        {
            [self.profilePicActionSheet dismissWithClickedButtonIndex:0 animated:YES];
            [self showPhotoPickerUsingSourceType:UIImagePickerControllerSourceTypeCamera];
        }
        if (buttonIndex == 1) // Photo Library
        {
            [self.profilePicActionSheet dismissWithClickedButtonIndex:0 animated:YES];
            [self showPhotoPickerUsingSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        }
        if (buttonIndex == 2) // Saved Photos Album
        {
            [self.profilePicActionSheet dismissWithClickedButtonIndex:0 animated:YES];
            [self showPhotoPickerUsingSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
        }
    }
}

- (void)showPhotoPickerUsingSourceType:(UIImagePickerControllerSourceType)sourceType
{
    ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
    if (status != ALAuthorizationStatusAuthorized)
    {
        // ...
    }
    else // status == ALAuthorizationStatusAuthorized
    {
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] initWithRootViewController:self];
        imagePicker.sourceType = sourceType;
        imagePicker.delegate = self;
        imagePicker.allowsEditing = YES;
        if ([UIImagePickerController isSourceTypeAvailable:sourceType])
        {
            [self presentViewController:imagePicker animated:YES completion:^{
                NSLog(@"imagePicker is on screen..."); // <-- App crashes before we get here
            }];
        }
        else
        {
            [Helper helperShowAlertWithTitle:@"Selected Source Type Not Available"];
        }
    }
}

Any help much appreciated. Thanks.


Solution

  • Change

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] initWithRootViewController:self];
    

    to

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];