1

Here's my goal: I'd like to show the UIImagePickerController from a TabBarController and once the photo is taken, I want the "Use" button to take me another view controller.

My problem: I have MainCameraTabController which inherits from UIViewController and serves as the class that orchestrates the launching of UIImagePickerController and the picker's delegate. When the picker is finished, I try to launch another a different ViewController from MainCameraTabController but I get the error,

*** Assertion failure in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:

If I put a timed delay between when the UIImagePickerController is dismissed and when I launch the next controller, it works okay but I'd like to do this more elegantly.

Is there a better way to structure my class inheritance so that I can have MainCameraTabController display the Picker and then a 2nd view controller?

// #
// # 1. Create the tab bar and add the MainCameraTabController:
// #
// tab1Controller and tab3Controller are also created
cameraTabController = [[MainCameraTabController alloc] init];

tabBarController = [[UITabBarController alloc] init];                                                                                                      

NSArray *tabViewControllers = [NSArray arrayWithObjects:tab1Controller, 
                                            cameraTabController
                                            tab3Controller, nil];

tabBarController.viewControllers = tabViewControllers;

self.window.rootViewController = self.tabBarController;


// #
// # 2. MainCameraTabController interface & implementation
// #

@interface MainCameraTabController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
}
- (void)showCamera;

@end

@implementation MainCameraTabController

// #
// # 3. Show the camera when the view loads
// #
- (void)viewDidLoad
{
    [self startCameraController:self usingDelegate:self];
}

- (void)showNextController
{
    FollowupController *fc = [[FollowupController alloc] initWithNibName:@"SomeView" bundle:nil];

    //  THIS IS THE PROBLEM
    [self presentModalViewController:cameraPicker animated: YES];
}

- (BOOL)startCameraController:(UIViewController *)controller
                usingDelegate:(id <UIImagePickerControllerDelegate, UINavigationControllerDelegate>)pickerDelegate 
{

    UIImagePickerController *cameraPicker = [[UIImagePickerController alloc] init];
    // configure the cameraPicker

    // #
    // # Apple's doc specifies that UIImagePickerController must be launched with   
    // # presentModalViewController
    // #

    [controller presentModalViewController:cameraPicker animated: YES];    
}

// UIImagePickerControllerDelegate method called when photo taking is finished
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{
    // work to handle the photo

    // Dismiss the picker
    [[picker parentViewController] dismissModalViewControllerAnimated: YES];
    [picker release];    

    [self showNextController];
}

@end

And on a related note, I checked to see what the picker's parentViewController is when

imagePickerController:didFinishPickingMediaWithInfo

is invoked and the parent is not MainCameraTabController but instead UITabBarController. Not sure why this is the case.

Jonas Anderson
  • 1,987
  • 4
  • 24
  • 28

1 Answers1

0

Because of the animation when dismissing the view, you need delay for the animation to finish before it can execute the next animation. You can solve this by setting the animated to NO. This will cut the animation and execute the next one immediately.

For the views, i had the similar experience, what i did was to switch the sequence of the views. I launched the view that i want to show after the picker first, in the viewDidload method, i created and display the picker so after the picker is dismissed, it will show the view that i want. If you want to make them look natural you could always play with the hidden property of the view to smoothen the flow.

Seyther
  • 652
  • 4
  • 6