UIImagePickerController custom overlay preview taken photo - objective-c

I'm creating custom camera controls using the UIImagePickerController. The problem I'm having is this:
When the user takes a photo, I would like to show a preview of the photo they have just taken. I have managed to do this by displaying a UIImageView over the camera viewfinder. The only problem is that there is a visible delay before the imageview is shown. Any ideas? My code is shown below
- (void)viewDidLoad
{
[super viewDidLoad];
picker = [[UIImagePickerController alloc] init];
[picker setSourceType:UIImagePickerControllerSourceTypeCamera];
overlayViewController = [[CameraOverlayViewController alloc] initWithNibName:nil bundle:nil];
[picker setCameraOverlayView:overlayViewController.view];
[picker setShowsCameraControls:NO];
[picker setDelegate:self];
[self.view addSubview:picker.view];
}
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *img = [info objectForKey:UIImagePickerControllerOriginalImage];
[overlayViewController.imgView setImage:img];
[overlayViewController.imgView setHidden:NO];
return;
}

The UIImagePickerController is a subclass of UINavigationController. You can create a custom preview view controller (just a view controller containing an image view and the cancel and use buttons) and push it on the image picker controller.

Related

nav bar nonresponsive after UIImagePickerController dismissed

On iOS 7 only, the navigation bar in my app does not respond to any touches after a UIImagePickerController is used and then dismissed (whether a pic has been selected or not). The screen below the navigation bar functions as normal, but it is now impossible to navigate Back in the app; the user is stuck on this screen.
I am launching the UIImagePickerController from code, though the rest of the app is laid out in storyboards.
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
mediaUI.mediaTypes = [NSArray arrayWithObject:(NSString *) kUTTypeImage];
mediaUI.allowsEditing = NO;
mediaUI.delegate = self;
[controller presentModalViewController: mediaUI animated: YES];
Thanks in advance for any help.
I hope you are performing these steps correctly!
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:NULL];
}
And when you are calling
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
Cheers!
I noticed that the log was showing "Unbalanced calls to begin/end appearance transitions for" the launching controller. I was launching the image picker controller immediately from another controller when it appeared. This works OK on iOS 8 but there needs to be a delay on iOS 7. I fixed it by calling my method after a brief delay:
[self performSelector:#selector(takePicture) withObject:nil afterDelay:.1];

Image Picker on ipad

I know image picker on the iPad needs to be a popover, and I keep trying but it won't work and crashes when I tap the button that calls the popover.
-(IBAction)addPhoto:(id)sender{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
popover=[[UIPopoverController alloc]
initWithContentViewController:imagePicker];
[popover presentPopoverFromRect:((UIButton *)sender).frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo {
// Delete any existing image.
NSManagedObject *oldImage = imageClass.image;
if (oldImage != nil) {
[imageClass.managedObjectContext deleteObject:oldImage];
}
// Create an image object for the new image.
NSManagedObject *myImage = [NSEntityDescription insertNewObjectForEntityForName:#"Image" inManagedObjectContext:imageClass.managedObjectContext];
imageClass.image = myImage;
// Set the image for the image managed object.
[image setValue:selectedImage forKey:#"image"];
[self dismissViewControllerAnimated:YES completion:nil];
}
Based on the exception you are getting, the problem is that the sender for the addPhoto method is actually a UIBarButtonItem, not a UIButton. You need to change how the popover is displayed from using the button's frame to being displayed from the bar button.
-(IBAction)addPhoto:(UIBarButtonItem *)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
popover = [[UIPopoverController alloc]
initWithContentViewController:imagePicker];
[popover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Try to create property to store Your popover controller or store content controller. Seems that one of view controllers releases right after end of method. Also, iOS 7 have awful behavior of UIImagePickerController in popover.
This is related question.

Present a view controller in the background

I am having a problem with presenting a view controller while another one is already presented.
In my app, I present a UIImagePickerController, which after selecting an image (either from the library or through the device's camera) should return to another view controller.
For example, let's say you clicked a camera button which launches the camera, and after you take a picture, the camera slides down, but the view you see is not the one with the camera button but a view which lets you edit the metadata of the image.
Does anyone know a way to accomplish this task?
Thanks ahead, iLyrical.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[picker dismissModalViewControllerAnimated:NO];
NewViewController *viewController = [[NewViewController alloc] init];
viewController.image = image;
[self presentModalViewController:viewController animated:NO];
}
And if you can use iOS 5.0 or newer:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[picker dismissViewControllerAnimated:YES completion:^(){
NewViewController *viewController = [[NewViewController alloc] init];
viewController.image = image;
[self presentViewController:viewController animated:NO completion:nil];
}];
}
Check Apple's doc on UIViewController Class Reference
If you are able to initialize the final viewController before presenting UIImagePickerController, you can try:
Initialize final viewController
Set it hidden or its view's alpha=0 and push non-animated
Present imagePicker viewController
Set the final viewController non-hidden
Dismiss modal viewController

Add A UIButton In A PopOverController - Xcode

I have an app which has a toolbar at the bottom with one of the options as Upload. On clicking on it, a PopOverController occurs which displays the list of photos to choose from.
After choosing a photo, I want to display a view (inside the PopOverController itself)which contains the photo alongwith the button called as Upload. On choosing my photo, currently my PopOverController is not getting dismissed. I have used the following lines of code :
-(IBAction)photolibrarypressed:(id)sender{
NSLog(#"hi");
UIImagePickerController *picker= [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:picker];
self.popoverController = popover;
popoverController.delegate = self;
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
imageView = [[UIImageView alloc] initWithFrame:[window bounds]];
[window addSubview:imageView];
imageView.hidden = YES;
[window makeKeyAndVisible];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
imageView.image = image;
NSLog(#"hellow");
[self dismissModalViewControllerAnimated:YES];
// need to show the upload image button now
upload.hidden = NO;
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissModalViewControllerAnimated:YES];
exit(0);
}
Can Someone help me to sort out the issue ??
Instead of calling
[self dismissModalViewControllerAnimated:YES];
call the same cancel method as int eh cancel method to handle dismissing it's modal view
[picker dismissModalViewControllerAnimated:YES]; // Dismisses modalView

UIViewController dismissModalViewControllerAnimated: causes main window to disappear

I want to present a modal mail dialogue like so in the iPad app:
MFMailComposeViewController* picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:title];
[picker setMessageBody:[NSString stringWithFormat:[self emailBody], title, [link absoluteString]] isHTML:YES];
[self.viewController presentModalViewController:picker animated:YES];
The following delegate is called when the user sends/cancels:
- (void) mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self.viewController dismissModalViewControllerAnimated:YES];
}
This works great in portrait mode. In landscape mode the right hand pane of the UISplitViewController completely disappears.
You can only present these from the primary view of your application. In this case, presenting from the UISplitViewController works.