I am trying to simply enable picking multiple images from photolibrary using the UIImagePickerController.I'm relatively new to XCode and I don't understand how to allow the user to pick multiple images from the UIImagePickerControler. This is my current code.Please help any body how to pick multiple images from UIImagePickerController.
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex)
{
case 0:
[self takeNewPhotoFromCamera];
break;
case 1:
[self choosePhotoFromExistingImages];
default:
break;
}
}
- (void)takeNewPhotoFromCamera
{
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
controller.sourceType = UIImagePickerControllerSourceTypeCamera;
controller.allowsEditing = NO;
controller.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
controller.delegate = self;
[self.navigationController presentViewController: controller animated: YES completion: nil];
}
}
-(void)choosePhotoFromExistingImages
{
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
controller.allowsEditing = NO;
controller.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypePhotoLibrary];
controller.delegate = self;
[self.navigationController presentViewController: controller animated: YES completion: nil];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self.navigationController dismissViewControllerAnimated: YES completion: nil];
UIImage *image = [info valueForKey: UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation(image, 0.1);
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
{
[self.navigationController dismissViewControllerAnimated: YES completion: nil];
}
With UIImagePickerController you are able to get only one picture. If you need to pick more you need a custom image picker, such as ELCImagePickerController. It works well! You can download it here.
As all said above, it is not possible using just ImagePickerController. You need to do it custom. Apple recently introduced PHASSET Library which makes this easy. There is a sample code also in the developer library. I am laying down the steps here.
Setup your own collection view
Load the collection view with pictures from gallery (using PHAsset, explained below)
Show each of the picture in your cellForItemAtIndexPath (using PHAsset, explained below)
In your didSelectItemAtIndexPath, keep track of which pictures were selected and add a tick mark image. Add it to a local array
When done, read from the picture array and process
Snippet code for Loading Images from gallery.
// Create a PHFetchResult object for each section in the table view.
#property (strong, nonatomic) PHFetchResult *allPhotos;
PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
allPhotosOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
if ( _isVideo == YES){
_allPhotos = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:allPhotosOptions];
}
else {
//_allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
_allPhotos = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:allPhotosOptions];
}
You now get all the images in your _allPhotos array which you will use like below in the cellForItemAtIndexPath
PHAsset *asset = self.allPhotos[indexPath.item];
//cell.representedAssetIdentifier = asset.localIdentifier;
cell.selectedTick.hidden = YES;
cell.isSelected = NO;
// Request an image for the asset from the PHCachingImageManager.
[self.imageManager requestImageForAsset:asset
targetSize:CGSizeMake(100, 100)
contentMode:PHImageContentModeAspectFill
options:nil
resultHandler:^(UIImage *result, NSDictionary *info) {
cell.photo.image = result;
}];
return cell;
Thatz it. Hope this helps.
The main reason for using hacks like shifting the UIImagePickerController up and showing selected images underneath was because the asset library alternative would involve the user being asked for location access due to the information about where the photo was taken being available in the image metadata.
In iOS 6 the user is asked if they want to allow the app to access their photos (not location) and you get asked this question for both the asset library approach and the UIImagePickerController approach.
As such I think that hacks like the above are nearing the end of their usefulness. Here is a link to a library providing selection of multiple images using the Assets library there are others.
Happy Coding!!!
Related
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.
This code for capturing image one by one from camera,but after taking one image next time camera will open but with black screen(like it,s shutter close).all other ios version its working,but not working in ios 8.please tell me how can i solve it?
-(void)openCamera
{
if(![PickerHandler doesDeviceSupportMediaType:ITEM_TYPE_PHOTO])
{
[PickerHandler showNoDeviceSupportWarningForMediaType:ITEM_TYPE_PHOTO withDelegate:self];
}
else
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
[self presentViewController:picker animated:YES completion:nil];
}
}
Go to Settings > Privacy > Pictures ... and check if your app have permission.
In the code, use this to verify camera access.
- (BOOL)authorizedCameraAccess
{
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
return (status == AVAuthorizationStatusAuthorized);
}
this code is not work in simulator.
UIImagePickerController *videoScreen = [[UIImagePickerController alloc] init];
videoScreen.sourceType = UIImagePickerControllerSourceTypeCamera;
videoScreen.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
videoScreen.allowsEditing = NO;
videoScreen.delegate = self;
[self presentViewController:videoScreen animated: YES completion:NO];
Implement This method
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissViewControllerAnimated:NO completion:NO];
}
I started to create a iOS App, and I started to have some troubles.
I have this code:
Taking a picture:
- (IBAction)tirarFoto:(id)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
Saving the picture to iOS Photos App:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[self.library saveImage:image toAlbum:#"Relembre" withCompletionBlock:^(NSError *error)
{
if (error!=nil)
{
NSLog(#"Big error: %#", [error description]);
}
}];
_fotoCamera.image = image;
[picker dismissModalViewControllerAnimated:NO];
}
Ok, so far, so good!
My problem is.
In another viewController I will need to load this picture.
I Have a Core Data in my project.
Can I Save the path(or something that can I load the picture) from the picture I have saved in Photos and save into Core Data, and after load in another view??
I Just need to now the path from picture that I took.
saveImage:toAlbum:withCompletionBlock: uses writeImageToSavedPhotosAlbum:orientation:completionBlock: method, whose block contains assetURL which is exactly what you need.
I have a table which is populated by a title and image entry. This is done by the following methods:
tablePhotoViewController.m
- (IBAction)takePicture:(UIBarButtonItem *)sender {
// check #1 - make sure our source type is supported
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// check #2 see if media type includes images
if ([mediaTypes containsObject:(NSString *)kUTTypeImage]) {
// create our image picker
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
picker.allowsEditing = YES;
[self presentViewController:picker animated:YES completion:nil];
}
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// do something with this image
UIImage *imagefromcamerabutton = [info objectForKey:UIImagePickerControllerEditedImage];
// handle the case where editting was not allowed...
if (!imagefromcamerabutton) imagefromcamerabutton = [info objectForKey:UIImagePickerControllerOriginalImage];
// save to photo albumn
ALAssetsLibrary *al = [Utils defaultAssetsLibrary];
[al writeImageToSavedPhotosAlbum:[imagefromcamerabutton CGImage] metadata:nil
completionBlock:^(NSURL *assetURL, NSError *error)
{
// once we know it's saved, grab the ALAsset and store
// it in our collection for display later
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
[self.photos addObject:myasset];
[self.tableView reloadData];
};
ALAssetsLibrary *assetslibrary = [Utils defaultAssetsLibrary];
[assetslibrary assetForURL:assetURL
resultBlock:resultblock
failureBlock:nil];
}];
[self dismissImagePicker];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.photos count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
ALAsset *asset = [self.photos objectAtIndex:indexPath.row];
[cell.imageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
[cell.textLabel setText:[NSString stringWithFormat:#"Thing %d", indexPath.row+1]];
return cell;
}
This works well, but the problem is that after the user closes the app, the cell data is erased. I would like these to be able to stay as photos which are continually associated with the table unless the user taps a button to delete it from the array. From my limited understanding of how this could be done it looks like i need to somehow implement NSUserDefaults is that right or is there a better practice to achieve this goal?
NSUserDefaults is loaded completely into memory when it is accessed. This means if you data source contains more than a few items this would be really slow or it could even crash when the phone runs out of memory.
But, when I understand you code correctly you are storing the photos in the camera roll. Therefore you have some kind of URL to the image already (the assetURL in your code).
For a quick and kind of dirty solution (which I find OK for small amounts of data which does not change often, I use NSCoding. So you can add the title and the assetURL into a NSDictionary and add the dictionary to the array of your data source. Then in dealloc call
[NSKeyedArchiver archiveRootObject:self.myDataSourceArray toFile:[self pathToFileInDocumentsDirectory]];
In viewDidLoad you can then get the data back you call:
self.myDataSourceArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[self pathToFileInDocumentsDirectory]];
If the data contains many items or the items are about to change much I tend to use Core Data or Sqlite. How to use those doesn't fit into this answer.
In my application i need to take video from simulator and i need to upload to server.can any one help to me.Please provide any solution as soon as possible.
Thanks & Regards
T.swathi
First, create a UIImagePickerController
On your class, you will need to implement the UIImagePickerControllerDelegate protocol and wire it up to the delegate property on the picker. You should be able to get the location of the media selected from didFinishPickingMediaWithInfo once the user has selected something.
//Check in iOS Device not in Simulator
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// this is the file system url of the media
NSURL* videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
// TODO: read in data at videoUrl and write upload it to your server
}
Use this function may be help full
-(void)selectVideoButtonClicked:(id)sender{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
[self presentViewController:imagePicker animated:YES completion:nil];
}
and take delege of "UIImagePickerControllerDelegate" & and import framework and using delegate function pick video from library
MobileCoreServices.framework first import in project and after than import in file CoreServices/CoreServices.h
- (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
// Handle a movie capture
if (CFStringCompare ((CFStringRef) mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo) {
NSString *moviePath = [[info objectForKey: UIImagePickerControllerMediaURL] path];
NSLog(#" Video Path %#",moviePath);
NSString *fileName = [[NSString alloc]init];
//If you wants get File Name Then you can use this
if ([moviePath rangeOfString:#"//"].location != NSNotFound) {
NSString *separatorString = #"//";
NSArray *disSplit = [moviePath componentsSeparatedByString:separatorString];
fileName = disSplit[1] ;
// [self videoUploadingDirect:moviePath];
}
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum (moviePath, nil, nil, nil);
}
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Thanks :)