views:

1967

answers:

3

I am trying to implement live camera functionality in my iPhone application and am running into trouble. Basically, the way it is structured is this: I provide a UINavigationController wherein the user can navigate to an image with a table view and (upon choosing one) a detail view.

They can then click on a button and take a new photo with the camera. Ideally, what should happen is that after taking the photo or canceling they go back to the navigation root where the images are listed again. For this, I am implementing the UIImagePickerController delegate within my main detail view controller.

All of that is implemented just fine except that last bit - I can access the photo, etc. but when attempting to return to that first listing - using popToRootViewControllerAnimated - I get an EXC_BAD_ACCESS error. Here is a reduced version of the relevant code (didFinishPickingMediaWithInfo ... imagePickerControllerDidCancel works the same way):

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    // Do some image processing stuff here...

    [picker dismissModalViewControllerAnimated:YES];
    [picker release];

    [self.navigationController popToRootViewControllerAnimated:YES];    
}

Commenting out that last line makes it work, but then it just goes back to the detail view with the original photo, not the listing.

Anyone?

Update: A detail I neglected to mention before... The pop does, in fact, appear to work to a degree. The camera picker is dismissed and it goes back to the listing. However, that's when the app dies (the selected table cell is still blue, from where the user tapped before). I also tried using popViewControllerAnimated instead with the exact same result.

+1  A: 

You problem here is [picker dismissModelViewController] and [picker release] i believe ... You do not need to release the picker, it is releasedd for u when u dismiss the modal view controller i believe (which you arent doing correctly from what i can s ee)...Either that or it has a reference count of 0 and should not be release, either way i recall doing something like this and having it crash because i released the picker...Also i noticed you are having the picker dismiss the modal view controller, are you sure this is what you are trying t o do? not [self dismissModalViewController] or which ever ViewController you pushed that view onto?

Daniel
I commented out the picker release and changed it to "self dismissModalViewControllerAnimated" (you were right, though - I had it wrong before), with the same result unfortunately. Worst thing is that the debugger isn't being especially helpful.
are you sure you are not overreleasing anything somewhere in your code ?
Daniel
Good catch! I had the same issue. I wish the error were better.
Peter DeWeese
A: 

The answer:
Use this: [self.navigationController dismissModalViewControllerAnimated:YES]; code instead of [picker dismissModalViewControllerAnimated:YES];
Now, you can remove this line from your code: [self.navigationController popToRootViewControllerAnimated:YES];

Tim van Elsloo
I made this change (as well as just "self dismissModalViewControllerAnimated"). I get the same result as before unless I remove the popToRootViewControllerAnimated bit. I can remove it as you suggest and prevent the crash, but my end goal is to have it pop back to the initial listing.
Well, I'm very sure you have to use self.navigationController if you dismiss the modal view-controller instead of the picker, because picker IS the modal viewcontroller. PopToRootViewController is not relevant for you (in this situation) because that is to navigate "back", but you want only to close the modal-view-controller (there are 2 ways to navigate in a Navigation Controller).Comment all lines of code, do you get that error again (I guess), because this error isn't specific for this piece of code.
Tim van Elsloo
+1  A: 

Hey,

Hope this isn't too late for you. I just ran into the same problem tonight and banged my head against my MBP for about 30min before I started getting a little creative.

I found two ways to make this work. Neither is intuitive, but here you go. Basically, it seems the issue might be caused by the fact that you are calling "pop" on the navigationController before the "dismiss" animation has finished.

I found that if I set the animation boolean on the dismiss to "NO", then it worked.

E.g.

[picker dismissModalViewControllerAnimated:**NO**];

Another option is to create a 2nd method that actually calls the "pop" function, and call it using a timer with a short offset. Just enough for the dismiss animation to run.

E.g.

-(void)popMe {
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissModalViewControllerAnimated:YES];
    [picker release];

    [self performSelector:@selector(popMe) withObject:nil afterDelay:0.1];   
}

That timing worked for me, you may have to adjust.

Hope that helps!

  • Andrew
Thanks Andrew! Turns out that I was able to restructure my code in such a way that I didn't need to do the dismissal in this manner, but I did try this and it seems to work great. I've seen a few other cases where timing comes into play in a similar manner (ie. when attempting to display a UIActivityIndicatorView).
of course it helps, but it's not a common solution.
slatvick
Slatvick,If you have a common solution, I'd love to see it. I'm not a fan of hacks like this, but it seemed necessary.- Andrew