So what am I trying to do here is just to open the camera roll from within a custom camera overlayView. I implemented the custom camera overlayView, created a UIImagePickerController, and replaced the default overlay with my custom one. Then I created another instance of UIImagePickerController, set the sourceType to PhotoLibrary and tries to present it when a button on the overlayView is pressed.
The below error message shows when i press the button:
Warning: Attempt to present <UIImagePickerController: 0x14da5440> on <UINavigationController: 0x14e63760> whose view is not in the window hierarchy!
Here is my code:
- (IBAction)select:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker
animated:YES completion:nil];
}
}
Does anyone know what's the problem here?
Thanks!
you need to use completion block for present one view controller when another view controller dismiss like following:
[self dismissViewControllerAnimated:YES completion:^{
[self presentViewController:imagePicker
animated:YES completion:nil];
}];
Related
My Storyboard contains a CameraViewController in which I designed my custom overlay view.
As long as I use it as one tab of my UITabbarController, the cameraOverlayView is visible. But if I segue to this view controller from any other VC, the overlay view is visible only for a fraction of a second, then only the preview image is visible.
#implementation CameraViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIImagePickerController *picker = [UIImagePickerController new];
if (![UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) return;
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.showsCameraControls = NO;
picker.allowsEditing = NO;
picker.cameraOverlayView = self.view;
[self presentViewController:picker animated:YES completion:nil];
}
I have tried any segue types, presentation styles, etc., the problem stays the same.
I inserted some logs in viewDidDisappear, and noticed that this function in fact is called, I guess that's the reason why the overlay disappears.
Keep in mind: If I just open the tab of my Tabbarcontroller, everything just works fine! The problem only occurs if I segue to the CameraVC.
Thanks in advance!
The solution is to select modal presentation style and "Over current context", because then the viewDidDisappear event is not triggered.
From Apple Documentation.
"This supports taking more than one picture without leaving the interface, but requires that you hide the default image picker controls".
On [self.imagePicker takePicture] the delegate didFinishPickingMediaWithInfo is being called but is still leaving the interface.
Any idea how can i prevent the controller from being dismissed?Here is my code of UIImagePickerController with custom overlay.
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.showsCameraControls = NO;
CameraOverlayView *overlay = (CameraOverlayView *)[self viewWithNibName:#"CameraOverlayView" owner:self];
overlay.frame = imagePicker.cameraOverlayView.frame;
imagePicker.cameraOverlayView = overlay;
overlay.imagePicker = imagePicker;
[self presentViewController:imagePicker animated:YES completion:nil];
overlay = nil;
I have same problem but i resolved this by using these classes in my code UzysAssetsPickerController for iOS
By using this i can select multiple images without dismissing the image picker. Hope this will help.
This solved my problem.Working perfectly now.Thank You everyone.
<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property(nonatomic,strong) UIImagePickerController *imagePicker;
overlay.imagePicker = _imagePicker;
overlay.imagePicker.delegate = overlay;
// may be it will help for you.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// if you want to dismiss controll then use the following code
[picker dismissViewControllerAnimated:YES completion:^{
}];
// if you wnat to being present it comment the above dismis code
}
Edit: I just figured out the problem is UIImagePicker and not video editor changing code to represent that.
I am trying to make it so when they hit the cancel button on the UIImagepicker it will dismiss it and will logout of Facebook and go to the main view.
This is what I have to dismiss.
-(IBAction)Logout:(id)sender
{
[[FBSession activeSession]closeAndClearTokenInformation ];
[self.parentViewController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController popToRootViewControllerAnimated:(YES)];
}
and here is how i present the image picker
//Create an image picker
UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
//Get the videos from the photo library
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//Set media types to movie tyeps
imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *) kUTTypeMovie, nil];
//present the controller
[self presentViewController:imagePicker animated:YES completion:nil];
The error I am getting is erminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSURL initFileURLWithPath:isDirectory:]: nil string parameter'
I am not even using initFileURLWithPath anywhere in my program so I have no idea what the problem seems to be right now. I have narrowed it down that the dismiss is causing the the error to happen and I'm not sure what is going wrong right now. Thanks.
Within your header file for your viewController you should already have the following delegates implemented
#interface ViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
This will allow you access to the UIImagePickerController's delegate methods which will fire once the UIImagePicker cancel button has been pressed. One of these methods is the one below didFinishPickingMediaWithInfo. You will need to add this method and dismiss the picker from here.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//Within this method you can capture/save etc the media you have just recorded etc too.
//Use the line below to dismiss the pickerController
[picker dismissViewControllerAnimated:YES completion:nil];
}
I hope this helps
When a user clicks a certain button,I want him to have the ability to choose between taking a picture and choosing a picture from a gallery. As of right now it seems to be one or the other. Should I create two buttons for this or is there a better what to accomplish this? I am hoping a way to click a button and iOS will natively give the user the choice.
-(IBAction)takePhoto:(id)sender
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
// image picker needs a delegate,
[imagePickerController setDelegate:self];
// Place image picker on the screen
[self presentModalViewController:imagePickerController animated:YES];
}
In my opinion the best way would be to Create for example 2 buttons
UIBarButtonItem * choosePhotoBtn
UIBarButtonItem * TakePhotoBtn
Then call the same IBAction when pressing either button, and put a condition in it to call the appropriate interface somehting like this:
-(IBAction) getPhoto:(id) sender {
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIBarButtonItem *) sender == choosePhotoBtn) {
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
} else {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentViewController:picker animated:YES completion:nil];
}
But these are the best options, I like the UIAlertView the most to be honest
To be honest thats more clicks for the user, but again thats my opinion .
Here's how you can do it, Create your UIAlertView , then put a condition in its deleguate method:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *BtnSelected = [alertView buttonTitleAtIndex:buttonIndex];
if([BtnSelected isEqualToString:#"choosePhotoBtn"] {
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
} else {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentViewController:picker animated:YES completion:nil];
}
When user press the button you can display UIAlertView or UIActionSheet, I would recommended UIAlertView for two button. And in the delegate method base on user selection you can make your logic to access camera or gallery.
There are two options -
First show the pickerController with source type as photo library. Then there is a property in UIImagePickerController called cameraOverlayView. You can set it to a custom view with the button at the bottom that on click switches the pickerController source type to camera.
Read the photo library and present them for selection in a custom view with a button to launch camera which would use the UIImagePickerController with sourceType as camera.
More about overlayView - [UIImagePickerController cameraOverlayView]
Sample code project from Apple - Using UIImagePickerController to Select Pictures and Take Photos
I have been beating my head on this for a few hours. I have some sample code (using a UINavigationController) when the view loads the camera roll will be presented. However, when I try to incorporate the same code into my app, which has a tabBarController, I get a blank modal UIImagePickerController. I didn't track down what I am doing wrong.
// bring up image picker
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
NSLog(#"UIImagePickerControllerSourceTypePhotoLibrary available");
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
ipc.allowsEditing = YES;
[self.tabBarController presentModalViewController:ipc animated:YES];
[ipc release];
}
Any insight would be appreciated.
Not sure what has changed, but this is possible by calling presentViewController from your tabBarController. This is the standard now and ensures your camera or image picker always gets presented as a full screen modal view.
For reference: presentViewController