Passing UIImage to second view controller lags transition - iphone

I'm using a UIImagePickerController to select an image from my photo album. Once I've selected the image, I'm passing the image through to a second view controller and displaying it in a UIImageView. See code below:
First view controller:
- (IBAction)selectPhoto
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentModalViewController:self.imagePicker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UploadViewController *uploadViewController = [[UploadViewController alloc] initWithNibName:#"UploadViewController" bundle:nil];
[uploadViewController setImage:[info objectForKey:#"UIImagePickerControllerOriginalImage"]];
[picker pushViewController:uploadViewController animated:YES];
}
Second view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the image view image
imageView.image = self.image;
}
The code does the job, however, when I push from the image picker to my second view controller, it lags as it's transitioning.
Ideally I would like a smooth transition but I would be happy if it just waited half a second or something and then moves smoothly.
Can any explain why this could be happening and how/if I can get around it?
Thanks.

The delay is probably from rendering the image, you could try having your UploadViewController's initial view contain an activity spinner then actually set the image in the viewDidAppear method, this method should be called after the animation is completed.

Try with this , here timer is introduced in order to provide delay(0.5sec) ,
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[NSTimerscheduledTimerWithTimeInterval:0.5 target:self selector:#selector(timerAction:) userInfo:info repeats:NO];
}
-(void)timerAction:(NSTimer *)timer
{
UploadViewController *uploadViewController = [[UploadViewController alloc] initWithNibName:#"UploadViewController" bundle:nil];
[uploadViewController setImage:[[timer userInfo]objectForKey:#"UIImagePickerControllerOriginalImage"]];
[picker pushViewController:uploadViewController animated:YES];
[uploadViewController release];
}

Related

how to call imagepickerdelegate method two times when picking images from dirrerent button

I'm relatively new to X Code
and
I m working on photo collage App , when i pick image from one picker then image picker is working properly but i want to pick different images from different imagepicker then image picker is not working properly
Anyone help me solve my problem. Here is my code
`
-(IBAction)imagepickMethod1:(id)sender
{
imagepicker=[[UIImagePickerController alloc]init];
imagepicker.delegate=self;
imagepicker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagepicker animated:YES];
button1.tag=100;
}
-(IBAction)imagepickMethod2:(id)sender
{
imagepicker1=[[UIImagePickerController alloc]init];
imagepicker1.delegate=self;
imagepicker1.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagepicker1 animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[picker dismissModalViewControllerAnimated:YES];
imagepicker.view.hidden=YES;
photoPreviewImageView.image=image;
}
-(void)imagePickerController1:(UIImagePickerController *)picker1 didFinishPickingImage:(UIImage *)image1 editingInfo:(NSDictionary *)editingInfo1
{
[picker1 dismissModalViewControllerAnimated:YES];
imagepicker.view.hidden=YES;
photoPreviewImageView1.image=image1;
}
`
//Take two imageView in your .h file
UIImageView *imgViewForFirstPicker;
UIImageView *imgViewForSecondPicker;
// Alloc these images in view did load
imgViewForFirstPicker = [[UIImaeView allo] initWithFrame:(give your rect)];
// Similarly for second imageView and add to both in self.view
-(IBAction)imagepickMethod1:(id)sender
{
UIImagePickerController *imagepicker=[[UIImagePickerController alloc]init];
imagepicker.delegate=self;
imagepicker.tag=100;
imagepicker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagepicker animated:YES];
}
-(IBAction)imagepickMethod2:(id)sender
{
UIImagePickerController *imagepicker1=[[UIImagePickerController alloc]init];
imagepicker1.delegate=self;
imagepicker1.tag=101;
imagepicker1.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagepicker1 animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage: (UIImage*)image editingInfo:(NSDictionary *)editingInfo
{
[picker dismissModalViewControllerAnimated:YES];
if(picker.tag == 100)
imgViewForFirstPicker.image=image;
else
imgViewForSecondPicker.image=image;
}
try this one hope it will help you
UIImagePickerController creates a pretty heavy object, So I don't think it is advisable to create multiple instances of it. May be this is what is causing the problem if you are doing the same.. It would be nice if you could share your code as well so we can have more insights into your problem
It is advisable to just use on image picker. From the code you provided you are trying to create two different imagepicker delegate methods, but in reality only one of them will be called both times.
You should create on instance of imagePicker and change its tag depending on which image you needed changed and then in the -didFinishPickingImage check if (picker.tag == SOME_TAG) then set appropriately.

UIImagePickerController takePicture

I want to use UIImagePickerController takePicture method.
the problem his that the UIImagePickerController is not show in the screen and the user cannot press the Use button to accept the img.
Is there is any way to skip this screen and go straight to :
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
for saving the image?
The only way that I have found to do this is to use a custom overlay for UIImagePickerController. You can do that with code akin to that below:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//create custom overlay and allocate it as "customOverlayView"
picker.cameraOverlayView = customOverlayView;
//do any other setup desired for picker
[self presentViewController:picker animated:YES completion:nil];
[picker release];
Now once the takePicture method is called, the delegate didFinishPickingMediaWithInfo: will be called immediately like you desire.

Why won't dismissmodalviewcontrolleranimated dismiss UIImagePickerController immediately on ios5?

I have a UITableViewController that pops up a UIImagePickerController, user takes a pic, hits the Use button, Picker dismisses to show a custom thumbnail spinner while the image is being processed, then the spinner is replaced by the actual thumbnail at the end of processing.
At least that's how it worked in iOS4. Now with iOS5 it just sits there processing until it's finished, and then everything works correctly. But I want that spinner in there so the user knows something's happening, otherwise it looks like it just hung.
So I have this:
- (void) actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex (NSInteger)buttonIndex {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = NO;
// yada, yada, yada
[self presentModalViewController:picker animated:YES];
[picker release];
}
And then this gets called when the user picks "Use":
- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissModalViewControllerAnimated:YES];
[self performSelectorOnMainThread:#selector(processImage:) withObject:info waitUntilDone:NO];
animate = true;
}
And then this gets called to perform the processing while the thumbnail is spinning:
- (void) processImage:(NSDictionary *)info
{
UIImage *image = nil;
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
// processing of image
animate = false;
[activityImageView stopAnimating];
[activityImageView release];
[self.tableView reloadData];
}
Like I said, it worked perfectly with iOS4, but with iOS5, no such luck. So what's the deal? The image picker gets dismissed eventually, so why doesn't it get dismissed immediately?
I'm not sure why there's a disparity between iOS4 & iOS5 on this point. But your description of the UI hanging is fairly consistent with the code you've shown. The perform selector on main thread is doing just that, performing the selector on the main thread, which is the thread you're calling from. Because of this setting waitUntilDone: to NO is meaningless since it's not being sent to another thread it's simply running in order. You would probably get the results you want just from swapping the order, like So:
[self dismissModalViewControllerAnimated:YES];
animate = true;
[self performSelectorOnMainThread:#selector(processImage:) withObject:info waitUntilDone:NO];
But please note that this would be risky at best, since I assume // processing of image contains no concurrency. I prefer blocks for concurrency. And on top of that I like nested blocks to make the concurrency easy to follow, for example:
-(void)doSomeStuffInBackground{
// Prepare for background stuff
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// Do background stuff
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI from results of background stuff
});
});
}
So with that in mind, I would suggest something more like this:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissModalViewControllerAnimated:YES];
[self processImage:info];
}
-(void)processImage:(NSDictionary *)info{
animate = true;
UIImage *image = nil;
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// processing of image here on background thread
dispatch_async(dispatch_get_main_queue(), ^{
// update UI here on main thread
animate = false;
[activityImageView stopAnimating];
[activityImageView release];
[self.tableView reloadData];
});
});
}
This would offload the main work to a background thread to let the UI stay responsive.
Try to use
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
instead of:
[[picker parentViewController] dismissModalViewControllerAnimated: YES];

Problem opening new ViewController after UIImagePickerController

I am trying to open up a new view (UnprocessedPhotoViewController) immediately after the delegate function for my UIImagePickerController returns a "didFinishPickingImage".
Unfortunately, it appears that I can either open the UIImagePickerController modal view, or switch to the UnprocessedPhotoViewController as a modal, but not both sequentially.
In the code below, a button press activates the pickPhoto IBAction. This code activates the UIImagePickerController successfully. After the user selects an image, the didFinishPickingImage delegate function is called, which stores the image to a variable, attempts to close the UIImagePickerController modal and open the UnprocessedPhotoViewController in a new modal.
Note: If I comment out the ImagePicker and run "showPhoto" directly, the UnprocessedPhotoViewController shows successfully. Also, if I make a new button to launch either view it works successfully, but I am unable to launch the views sequentially. I would expect that after a user selected the image, the new view would be launched which would allow the user to process the image.
What is the correct way to guarantee that the ImagePicker modal closes and then to open the UnprocessedPhotoViewController?
Thanks!!!
Code:
- (IBAction)pickPhoto:(id)sender{
//TODO: To be replaced with the gallery control launching code
// Load Image Selection Code
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:self.imgPicker animated:YES];
}
// Dummy function assumes you either picked (or took a picture =D) of Angie and moves you right to the unprocessed viewing screen.
- (void) showPhoto{
// Start new view controller
[self dismissModalViewControllerAnimated:YES];
UnprocessedPhotoViewController *upViewController = [[UnprocessedPhotoViewController alloc] initWithNibName:#"UnprocessedPhotoViewController" bundle:nil];
upViewController.imageView.image = selectedImage;
upViewController.delegate = self;
upViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:[upViewController animated:YES]];
[upViewController release];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img {
selectedImage = img;
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[self dismissModalViewControllerAnimated:YES];
[self showPhoto];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
Implement viewDidAppear in your root view controller and based on member data decide to call showPhoto or not. The following example simply re-presents the UIImagePicker but any new modal view will work. viewDidAppear is called any time your root view controller’s view appears so you have to make sure the context is known when it is called. But it is the deterministic way to know that the modal view controller is gone.
- (IBAction) showPicker: (id) sender
{
UIImagePickerController* picker = [[[UIImagePickerController alloc] init] autorelease];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
picker.allowsEditing = YES;
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
imageChosen = YES;
[self dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
imageChosen = NO;
[self dismissModalViewControllerAnimated:YES];
}
- (void) viewDidAppear: (BOOL) animated
{
if ( imageChosen )
{
[self showPicker: self];
}
}
Another way to do this is to wrap the built-in dismissal animation with your own animation, and then catch the animationDidStop "event." This creates a composite animation, so when the built-in animation is done, your (empty) wrapper animation finishes you and alerts you that you're done.
This is slightly cleaner than the other answer here, IMO, as you don't need to keep a state variable or override viewDidAppear: (in my app, the view controller presenting the picker is quite a few objects removed from the utility code that handles picker management, and that would mean any view controller using my shared utility would have to override viewDidAppear:, or else fail to work):
-(void)dismissalAnimationDone:(NSString*)animationID
finished:(BOOL)finished context:(void*)context
{
UIImage* image = (UIImage*) context;
// present controllers as you please
}
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[UIView beginAnimations:#"dismissal wrapper" context:image];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(dismissalAnimationDone:finished:context:)];
[self.delegate dismissModalViewControllerAnimated:YES];
[UIView commitAnimations];
}

UIImagePicker doesn't showing selected image

I'm new to iPhone and I'm using this code to select an image from the iPhone library and show it in imageView. The library is showing images, but when I'm selecting the image, it doesn't appear in the image view..
- (void)viewDidLoad {
[super viewDidLoad];
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
Please can you tell me what's the problem with the code?
Try with:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = pickedImage;
[self dismissModalViewControllerAnimated:YES];
}
UIImagePickerControllerOriginalImage is a string constant that could be different from #"UIImagePickerControllerOriginalImage" string.
Then, it's safe and more clear to former set the image view, and latter to dismiss the modal view controller.
Pay attention that you should invoke dismissModalViewControllerAnimated: on self because you are dismissing the modal view controller "owned" by self.
Bye!
I fixed my issue of "grey box appearing instead of an image in UIImageView".
I forgot to make the Background color of the UIIMageView to be CLEAR COLOR. THe problem was solved by setting background color to clearColor.
Was using XIB and you should also check if anything is laid out wrong in Interface builder in case you are using interface builder to create UI.