IOS image picker in navigation view controller - ios

I am trying to browse an image and display in imageview using UIImagePickerController. Basically the view I am using to browse the image is based on navigationController.
But using the below code after I select the image and come back to view, I can see that the view is flickering to left right and the image is not showing in image view.
Actually the entire source code is quit long, thats why I post the image picker part only. If required I can post more code.
RegistrationFormViewController.h
#interface RegistrationFormViewController : ViewController
<UIImagePickerControllerDelegate,UINavigationControllerDelegate,CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
UIImagePickerController *imagePickerController;
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (weak, nonatomic) IBOutlet UIImageView *imageUser;
- (IBAction)registerBt:(id)sender;
RegistrationFormViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
_barButtonBack.target = self.revealViewController;
_barButtonBack.action = #selector(revealToggle:);
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected)];
singleTap.numberOfTapsRequired = 1;
[self.imageUser setUserInteractionEnabled:YES];
[self.imageUser addGestureRecognizer:singleTap];
}
-(void)tapDetected{
NSLog(#"single Tap on imageview");
imagePickerController = [[UIImagePickerController alloc]init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
#pragma mark - ImagePickerController Delegate
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
// Dismiss the image selection, hide the picker and
//show the image view with the picked image
[picker dismissViewControllerAnimated:YES completion:nil];
[self.imageUser setImage:image];
self.imageUser.contentMode = UIViewContentModeScaleAspectFill;
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}

There is no issue in your code that you showed here. However try this in didFinishPickingImage -
dispatch_async(dispatch_get_main_queue(), ^{
self.imageUser.contentMode = UIViewContentModeScaleAspectFill;
[self.imageUser setImage:image];
});
and move this code to viewDidLoad
imagePickerController = [[UIImagePickerController alloc]init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
you can also check whether you are getting the image or not using breakpoint.

try this delegate method
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:NULL];
}

In viewcontroller.m file, just put this code:
#import <AssetsLibrary/AssetsLibrary.h>
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
- (IBAction)Gallery:(id)sender {
self.ImagePickerController = [[UIImagePickerController alloc]init];
self.ImagePickerController.delegate = self;
self.ImagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentViewController:self.ImagePickerController animated:YES completion:nil];
}
- (IBAction)Camera:(id)sender {
self.ImagePickerController = [[UIImagePickerController alloc]init];
self.ImagePickerController.delegate = self;
self.ImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:self.ImagePickerController animated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
NSURL *imageUrl = (NSURL *)[info objectForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *representation = [myasset defaultRepresentation];
CGImageRef resolutionRef = [representation fullResolutionImage];
if (resolutionRef) {
UIImage *image = [UIImage imageWithCGImage:resolutionRef scale:1.0f orientation:(UIImageOrientation)representation.orientation];
self.SelectedImage.image =image;
}
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"cant get image - %#",[myerror localizedDescription]);
};
if(imageUrl)
{
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc]init];
[assetslibrary assetForURL:imageUrl resultBlock:resultblock failureBlock:failureblock];
}
}
In viewcontroller.h file
#interface ViewController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property (nonatomic)UIImagePickerController *ImagePickerController;
#property (weak, nonatomic) IBOutlet UIImageView *SelectedImage;

Related

UIPickerController memory leak after selecting photo

I am having a memory leak whenever I select a photo within my image picker controller. I have tried doing my own research as to why this happens but I have found nothing close to my situation. Various tutorials I have learnt from have a memory leak when using the image picker controller as well. All I am doing is choosing a photo and then the image picker controller dismisses. I have tried finding a solution for many days now, but no luck, I tend to try to find solutions before asking for help, any help is greatly appreciated, here is my code.
#property (nonatomic, strong) UIImagePickerController *imagePicker;
#property (nonatomic, strong) UIImage *image;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
if (self.image == nil && [self.videoFilePath length] == 0) {
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = NO;
self.imagePicker.videoMaximumDuration = 10;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
self.imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:self.imagePicker.sourceType];
[self presentViewController:self.imagePicker animated:YES completion:nil];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImage *newImage = [self resizeImage:self.image toWidth:200 andHeight:200];
self.image = newImage;
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
}
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
// A video was taken/selected!
NSURL *videoUrl = info[UIImagePickerControllerMediaURL];
self.movieUrl = videoUrl;
self.videoFilePath = videoUrl.absoluteString;
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// Save the video!
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(self.videoFilePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(self.videoFilePath, nil, nil, nil);
}
}
}
[self dismissViewControllerAnimated:YES completion:nil];
}
When I use instruments I get, that the responsible instance is in Core Foundation. CFString. I am not very familiar with debugging memory leak's like these in Objective-C. I'd appreciate a hand here! Thank You.
The leak is coming from Apple's code. The only thing you are doing wrong is retaining the UIImagePickerController as an instance property. Stop doing that; create the UIImagePickerController as a temporary local variable each time you present it. Apart from that, there's nothing you can do.

didFinishPickingMediaWithInfo is not to work

-(void)cameraAndPhotoAlbums{
self.actionSheet = [[UIActionSheet alloc] initWithTitle:#"title" delegate:self cancelButtonTitle:#"cancel" destructiveButtonTitle:nil otherButtonTitles:#"Photo album",#"camera", nil];
[self.actionSheet showInView:self.view];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex==0) {
UIImagePickerController * imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
} else if(buttonIndex==1) {
UIImagePickerController * imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
[picker dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerControllerDidCancel:(id)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
}
But at the time of photo album selected photos will only perform the cancel but finish don't perform, tried this item anywhere to write all can't, I again open a project can go agent, a great god save stunned me..
Here is a sample code for you to study:
ViewController.h
#interface ViewController : UIViewController<UIImagePickerControllerDelegate>
{
UIImagePickerController * imagePicker;
}
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)setImageToImageView:(UIButton *)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(#"%#",NSHomeDirectory());
imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Image Picker Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
NSLog(#"Image picked");
self.imageView.image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary)
{
NSData * data = UIImageJPEGRepresentation([info valueForKey:#"UIImagePickerControllerOriginalImage"], 0.5);
NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/image.JPEG"];
[data writeToFile:path atomically:true];
}
else
{
UIImageWriteToSavedPhotosAlbum([info valueForKey:#"UIImagePickerControllerOriginalImage"], nil, nil, nil);
}
[self dismissViewControllerAnimated:true completion:nil];
}
- (IBAction)setImageToImageView:(UIButton *)sender
{
if (sender.tag == 101)
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[self presentViewController:imagePicker animated:true completion:nil];
}
#end
This code works, tested it on a device.

Xcode: Add attachment using picker to email

I have developed an app that allows the user to choose a video from the photo gallery and send it as an attachment in an email. I am able to choose a video from the gallery and proceed with sending the email but the video does not get attached with the email. There are no errors in the console.
ViewController.h:
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <MessageUI/MessageUI.h>
#interface ViewController : UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate,MFMailComposeViewControllerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)choose:(id)sender;
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIAlertController *myAlertController = [UIAlertController alertControllerWithTitle:#"MyTitle"
message: #"MyMessage"
preferredStyle:UIAlertControllerStyleAlert ];
[self presentViewController:myAlertController animated:YES completion:nil];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)choose:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
[self performSelector:#selector(email:) withObject:chosenImage afterDelay:0.5];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)email:(UIImage *)choosenImage{
NSString *iOSVersion = [[UIDevice currentDevice] systemVersion];
NSString *model = [[UIDevice currentDevice] model];
NSString *version = #"1.0";
NSString *build = #"100";
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:[NSArray arrayWithObjects: #"support#myappworks.com",nil]];
[mailComposer setSubject:[NSString stringWithFormat: #"MailMe V%# (build %#) Support",version,build]];
NSString *supportText = [NSString stringWithFormat:#"Device: %#\niOS Version:%#\n\n",model,iOSVersion];
supportText = [supportText stringByAppendingString: #"Please describe your problem or question."];
[mailComposer setMessageBody:supportText isHTML:NO];
NSData *data = UIImagePNGRepresentation(choosenImage);
[mailComposer addAttachmentData:data mimeType:#"image/png" fileName:#""];
[self presentViewController:mailComposer animated:YES completion:nil];
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Any suggestion/help would be much appreciated. Thank you.
You mentioned that you're trying to attach a video, and you've configured your UIImagePickerController to limit the mediaTypes to only videos. The problem then is that you're asking for the "edited image" in the "didFinishPickingMediaWithInfo" method:
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
The user did not pick an image - they picked a video. You need to use this instead:
NSURL *chosenVideoUrl = info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:chosenVideoUrl];
You can then pass the videoData to your email method and attach to the email. Be sure to update the mimeType from "image/png" to "video/mp4", as well.
If u need to attach both video and image you have write to code for both,but you written only for attaching an image.You can try the code below for getting both
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
if ([[info objectForKey:UIImagePickerControllerMediaType] isEqual:(NSString *)kUTTypeMovie]) {
NSString *videoURL = info[UIImagePickerControllerMediaURL];
[self emailImage:nil orVideo:videoURL];
}else {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
[self emailImage:chosenImage orVideo:nil];
}
[picker dismissViewControllerAnimated:YES completion:NULL];
}
UIImagePickerControllerMediaURL will return file url unlike UIImagePickerControllerEditedImage ,so can use NSData method dataWithContentsOfFile as bellow.
if (choosenImage) {
NSData *data = UIImagePNGRepresentation(choosenImage);
NSString *filename = [NSString stringWithFormat:#"Image_%#.png",TimeStamp];
[mailComposer addAttachmentData:data mimeType:#"image/png" fileName:filename];
[self presentViewController:mailComposer animated:YES completion:nil];
}else {
NSData *data = [NSData dataWithContentsOfFile:videoFile];
NSString *filename = [NSString stringWithFormat:#"Video_%#.mp4",TimeStamp];
[mailComposer addAttachmentData:data mimeType:#"video/mp4" fileName:filename];
[self presentViewController:mailComposer animated:YES completion:nil];
}
it will be good if you give a filename for the attachment it will be help full after it downloading.if you wish you can use a TimeStamp for that.
#define TimeStamp [NSString stringWithFormat:#"%f",[[NSDate date] timeIntervalSince1970] * 1000]

send me to detail view after taking picture with UIImagePickerController

I'm stuck on the following issue: When I'm taking a picture with UIImagePickerController i want to send the user to another view where the selected image is visible and he/she can fill some more information. But the detailview doesn't show up, instead of that when I take the picture the app hangs, even though the picture is saved on my phone. What can I do?
My code:
#interface PhotoViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
#property (nonatomic, strong) UIImagePickerController *imagePicker;
#property (nonatomic, strong) UIImage *image;
#end
#import "PhotoViewController.h"
#import "PostViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
#implementation PhotoViewController
- (void)viewDidLoad {
// Do any additional setup after loading the view.
[super viewDidLoad];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (self.image == nil) {
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = NO;
self.imagePicker.videoMaximumDuration = 10;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
} else {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
self.imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:self.imagePicker.sourceType];
[self presentViewController:self.imagePicker animated:YES completion:nil];
}
}
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:NO completion:nil];
[self.tabBarController setSelectedIndex:0];
}
-(void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// A photo was taken/selected!
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// Save the image!
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
}
}
}
I've also posted my Storyboard to make things clear.
Your screenshot is too small to be legible. Post a link to a file on another site.
In any case, it looks to me like the problem is that you're not dismissing the image picker.
-(void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
//--------------------------------------------------
//This is the line you're missing
picker.dismissViewControllerAnimated(true, completion: nil)
//--------------------------------------------------
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// A photo was taken/selected!
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// Save the image!
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
}
}
}

2 UIButtons to set 2 UIImageViews

I've 2 UIButtons, I want both buttons to pick an image, button1 is setting an image to imageview1 and button2 to imageView2. I now created button1 which picks an image and set imageView1 to that image, but if I'm creating button2, I don't now what I have to do in:
- (IBAction)chooseImage1:(id)sender {
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
}
- (IBAction)chooseImage2:(id)sender {
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
}
UIImage *image;
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *mediaURL;
mediaURL = (NSURL *)[info valueForKey:UIImagePickerControllerMediaURL];
image = (UIImage *)[info valueForKey:UIImagePickerControllerOriginalImage];
imageView1.image=image;
[picker dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
Create an index in your .h file. Something like
NSUInteger *selectedImageIndex;
And in your .m file :
- (void)showImagePicker:(UIImagePickerControllerSourceType)source{
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = source;
ipc.allowsEditing = YES;
ipc.delegate = self;
[self presentModalViewController:ipc animated:YES];
}
- (IBAction)chooseImage1:(id)sender {
selectedImageIndex = 1;
[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
}
- (IBAction)chooseImage2:(id)sender {
selectedImageIndex = 2;
[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *img = [info objectForKey:#"UIImagePickerControllerEditedImage"];
if (!img)
img = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
if (selectedImageIndex == 1)
imageView1.image=img;
else
imageView2.image = img;
[picker dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
But then again, this is just one way to do it.

Resources