On my app I have a cameraOverlayView
over my open camera with custom controls for the camera buttons. The app allows the user to take several pictures before closing the camera, so the shutter button does not call dismissViewControllerAnimated
, instead there's a close button for when you're done taking pictures.
Now, one of the buttons on the camera overlay is a gallery button to allow the user to pick a saved image instead of shooting a new one. I've tried two different approaches to make this work, both failed.
First approach
Use the same UIImagePickerController
instance that is currently presenting the overlay and switch the sourceType
to library. It does present the gallery then, but when a photo is tapped, I can't dismiss the galley without dismissing the whole overlay.
Second approach
Create a separate instance of UIImagePickerController
, set the sourceType
to gallery and attempt to call presentViewController
, which then fails with the warning:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
Does anyone have a solution for this issue? Is this even possible?
Try this~~ I think it is your goal.
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIImagePickerController *imagePicker;
@end
@implementation ViewController
@synthesize imagePicker = _imagePicker;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
sleep(2);
_imagePicker = [[UIImagePickerController alloc] init];
[_imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[_imagePicker setDelegate:self];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 100, 30)];
[button setTitle:@"Library" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor darkGrayColor]];
[button addTarget:self action:@selector(gotoLibrary:) forControlEvents:UIControlEventTouchUpInside];
[_imagePicker.view addSubview:button];
[self presentViewController:_imagePicker animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)gotoLibrary:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker.view setFrame:CGRectMake(0, 80, 320, 350)];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
[imagePicker setDelegate:self];
[_imagePicker presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
@end
The second approach is correct. I don't see your code, but I think that your controller hierarchy is something similar to this:
Main VC ---present---> Camera VC
so, if you call
[self presentViewController:picker animated:YES completion:^{}];
from your Main VC, you are attempting to show another VC from an "hidden" one (covered by the Camera VC).
The key is to take a reference to your camera VC (let's call it cameraVC) and do something similar from Main VC:
[cameraVC presentViewController:theOtherPicker animated:YES completion:^{}];
doing this, the "present" action is done by the Camera VC (visible) without warnings, and not by the hidden Main VC.
You could code your own custom gallery views for selecting photos and then add that to the cameraOverlayView
subview hierarchy.
There must be open source projects on GitHub, which show how to make these views, somewhere. Alternatively, I happen to have released a control very similar to what you are looking for if you don't want to start from scratch.
It's quite a simple procedure really — a collection view with a datasource backed by the AssetsLibrary
framework.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With