Reputation:
-(void) openPhotoLib:(id)sender {
[self dismissModalViewControllerAnimated:YES];
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[imagePicker setDelegate:self];
[self presentModalViewController:imagePicker animated:YES];
NSLog(@"openPhotoLib called");
}
Nothing happens except for the NSLog, even though my view controller is a subclass of UINavigationController and UIImagePickerDelegate. Does anyone have any insight or experience with UIImagePickerController?
I should note that I'm primarily using an iPhone for testing.
SOLUTION: Make a new class that subclasses ONLY UINavigationBarDelegate and UIImagePickerDelegate. In that classes's viewDidAppear, put the code to modally present the imagePicker. Create an instance of this class inside the method (inside another class, import the .h file and all) and the modally present that class.
^ I take it back. The modal animations was the real problem. Trying to use another class instance for this messes up the method implementations of UIImagePicker.
Upvotes: 0
Views: 267
Reputation: 3716
The problem is due to dismissModalViewControllerAnimated
and presentModalViewController
being called one after the other.
The dismiss action takes some time as it has to animate the view being dismissed. During the animation, it is still the top Modal View. So, you cant present another model view during that time. If you try then the call fails and does nothing.
To fix, use [self dismissModalViewControllerAnimated:NO];
i.e no animation.
If you still want animation then follow one of these solutions:
Problem opening new ViewController after UIImagePickerController
Correct way of showing consecutive modalViews
Upvotes: 1
Reputation: 69027
EDIT:
If using storyboards, you should define prepareFroSegue
in your delegate:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"AddPlayer"])
{
PlayerDetailsViewController
*playerDetailsViewController =
(PlayerDetailsViewController *) segue.destinationViewController;
playerDetailsViewController.delegate = self;
}
}
(source)
Am I not sure, but I think that the call:
[self dismissModalViewControllerAnimated:YES];
might interfere with the following call
[self presentModalViewController:imagePicker animated:YES];
since both are done within the same run loop.
I would suggest doing like this:
define a method to encapsulate the call to presentModal...
- (void)presentPicker:(...)picker {
[self presentModalViewController:imagePicker animated:YES];
}
replace the original call to presentModal... with:
[self performSelector:@selector(presentPicker:) withObject:picker afterDelay:0.0];
Explanation: by using performSelector
the way I suggest, we are simply enqueuing the call to presentPicker in the run loop (without any delay actually, since we specify 0.0 as a delay value). In this way, we give UIKit a chance to dismiss the modal view and do all necessary clean up before we try and present the next modal view.
The reason to define presentPicker
as a method is that performSelector
only allows to specify one single argument (instead of the two that presentModal...
requires).
Hope this helps.
Upvotes: 0