1

I have the following code to load a UIImagePickerController which works fine.

    UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
    mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    mediaUI.delegate = self;
    [controller presentModalViewController: mediaUI animated: YES];
    return YES;

I would like to load a modal view with some help information on how to use the UIImagePickerController:

UIStoryboard *storyboard = self.storyboard;
HelpViewController *svc = [storyboard instantiateViewControllerWithIdentifier:@"HelpViewController"];
[self presentViewController:svc animated:YES completion:nil];

How can I display the UIImagePickerController after the user dismisses the HelpViewController view?

DD.
  • 21,498
  • 52
  • 157
  • 246
  • i dont know if it works dismiss and after use presentviewcontroller. You could load model view to help information and with some action button for example you could go to next viewcontroller using again presentviewcontroller...and when you not go any utility from both view just give dismiss view controller... you can also create a navigation controller.. – Juan Munhoes Junior Feb 18 '13 at 00:49

1 Answers1

3

Don't be tempted to move directly from HelpViewController to UIImagePickerController, you need to get there via your mainViewController.

Let's put your code into a method...

- (void) presentImagePicker {
    UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
    mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
    mediaUI.delegate = self;
    [controller presentModalViewController: mediaUI animated: YES];
    return YES;
}

(Note that presentModalViewController:animated is depracated since ~iOS5, and you should really replace it with [controller presentViewController:mediaUI animated:YES completion:nil];)

Let's call your viewControllers mainVC, helpVC and imageVC. There are two ways you can implement this.

method 1 - performSelector

The quick-and-slightly-dirty solution is to do this in your helpVC's dismiss button method:

- (IBAction)dismissHelpAndPresentImagePicker:(id)sender 
{
    UIViewController* mainVC = self.presentingViewController;
    [mainVC dismissViewControllerAnimated:NO completion:
     ^{
         if ([mainVC respondsToSelector:@selector(presentImagePicker)])
         [mainVC performSelector:@selector(presentImagePicker)];
     }];
}

It's slightly dirty because you need to ensure that presentImagePicker is implemented in mainVC - the compiler will give you no warnings if it is not. Also you are running a completion block after it's object has been dismissed, so there's no certainty it's going to work (in practice, it does, but still...)

Note that you have to assign the pointer self.presentingViewController's to a local variable (mainVC). That's because when helpVC is dismissed, it's presentingViewController property is reset to nil, so by the time you get to run the completion block you cannot use it. But the local variable mainVC is still valid.

method 2 - protocol/delegate

The clean way to do this is to use a protocol in helpVC to declare a delegate method, and make mainVC the delegate. This way the compiler will keep track of everything and warn you if it is not correctly implemented.

Here are the steps to do that:

In helpVC.h add this protocol above the @interface section:

@protocol helpVCDelegate
    - (void) dismissHelpAndPresentImagePicker;
@end

In helpVC.h interface section declare a property for its delegate:

@property (nonatomic, weak) id <helpVCDelegate> delegate;

(the <helpVCDelegate> tells the compiler that the delegate is expected to conform to the protocol, so it will have to implement dismissHelpAndPresentImagePicker)

In helpVC.m your method can now look like this:

- (IBAction)dismissHelpAndPresentImagePicker:(id)sender 
{
    [self.delegate dismissHelpAndPresentImagePicker];
}

In MainVC, when you create HelpVC (=svc in your code), set MainVC as it's delegate:

HelpViewController *svc = [storyboard instantiateViewControllerWithIdentifier:@"HelpViewController"];
svc.delegate = self;
[self presentViewController:svc animated:YES completion:nil];

And be sure to implement the delegate method dismissHelpAndPresentImagePicker

- (void) dismissHelpAndPresentImagePicker
{
    [self dismissViewControllerAnimated:NO completion:^{
           [self presentImagePicker];
         }];

}

Personally I would always use method 2. But I offered up a that solution earlier today to a similar question, and the questioner seemed to think protocol/delegate was overcomplicated. Maybe my answer just made it seem so, I have tried to simplify it here.

Community
  • 1
  • 1
foundry
  • 31,615
  • 9
  • 90
  • 125
  • @DD Thanks for accepting my answer but I noticed an error - we weren't explicitly dismissing the HelpVC in the delegate version... I have updated it. – foundry Feb 18 '13 at 11:10
  • @DD - updated again... `presentImagePicker` is better off in a completion block so it is not triggered until `dimissViewController` has finished it's dismissing. – foundry Feb 20 '13 at 03:12
  • I used the "dirty" method to call an imagepickercontroller from a uiview that was in a tabarcontroller - worked wonderfully - thanks! – Zachary Fisher Dec 22 '14 at 18:29