Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Presenting camera roll UIImagePickerController over open camera

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?

like image 799
Rafael Avatar asked Jan 15 '13 02:01

Rafael


3 Answers

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
like image 167
Steven Jiang Avatar answered Nov 16 '22 12:11

Steven Jiang


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.

like image 28
LombaX Avatar answered Nov 16 '22 12:11

LombaX


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.

like image 1
Benjamin Mayo Avatar answered Nov 16 '22 11:11

Benjamin Mayo