UIImagePickerController dismissModalViewController - iphone

I am trying to invoke UIImagePickerController to select a movie on iPhone 3GS and when the movie is selected, i just dismiss it and present MyViewController modally with a configured delay of 1.0 seconds. What I notice is 10% of the times, presentModalViewController on MyViewController does nothing whereas it works 90% of the times. I want to understand why is this behavior and what is the remedy. Here is the sample code:
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoURL = nil;
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.movie"])
{
videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
}
picker.delegate = nil;
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[self performSelector:#selector(launchMyViewController:) withObject:nil
afterDelay:1.0];
}
-(void) launchMyViewController:(id) obj
{
MyViewController *myCtrl = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:[NSBundle mainBundle] controller:self];
[self presentModalViewController:myCtrl animated:YES];
[myCtrl release];
NSLog(NSStringFromClass([self.modalViewController class]));
[path release];
}
I have put NSLog statement to print the self.modalViewController class name and what I notice is that 10% of the times when myCtrl is not fired modally, the self.modalViewController.class is UIImagePickerController. Otherwise, the self.modalViewController.class is MyViewController. I want to know why is the behavior so unpredictable and what is the workaround or other way to achieve the same thing I intend.

I'm going to guess that using the performSelector:afterDelay: call is the problem. Try calling your launch method immediately, instead of through the delay.

Related

iOS 7 UIImagePickerController Camera Covered with Static image

iOS 7 using UIImagePickerController to take picture twice, at second time will show a static image covered the camera, how to reset the camera.
I'm try to take picture one by one, and keep take 5 pictures.
It works on iOS6.
on iOS7, it works fine at the first time, but when it take picture at second time, it will show a static dark image on screen, how to clear or reset it, although take picture works, but user can't see what will capture with camera.
bool fistTimeToShow = YES;
-(void) viewDidAppear:(BOOL)animated{
if (fistTimeToShow) {
fistTimeToShow = NO;
self.imagePickerController = nil;
[self tackImage];
}
}
-(void)tackImage{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imagePickerController = [[UIImagePickerController alloc]init];
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePickerController.showsCameraControls = YES;
self.imagePickerController.delegate = self;
[self presentViewController:self.imagePickerController animated:NO completion:nil];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(#"====== imagePickerController:didFinishPickingMediaWithInfo ======");
[self.imagePickerController dismissViewControllerAnimated:NO completion:nil];
//...deal with the image capture...
self.imagePickerController = nil;
[self tackImage];
}
Update
I change the dismiss function to put the [self tackImage]; in block. And now it always show the fist image took.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(#"====== imagePicker: didFinish ======");
self.imagePickerController = nil;
[self dismissViewControllerAnimated:NO completion: ^{
[self tackImage];
}];
}
I'm trying to find a way to clear the image. But I don't know where the image saved yet.
Update2
use
[self performSelector:#selector(presentCameraView) withObject:nil afterDelay:1.0f];
and function
-(void)presentCameraView{
[self presentViewController:self.imagePickerController animated:NO completion:nil];
}
to replace. [self presentViewController:self.imagePickerController animated:NO completion:nil]; it works on my device anyway, but I don't even know why.
Update3
I have set the userInteractionEnabled to NO when Delay:1.0f to avoid other problems, and may be also need set the navigationBar and tabBar for specifically use.
I had exactly the same issue under iOS 7 using Xamarin.iOS.
What has helped, is adding GC.Collect() in didFinishPickingMediaWithInfo method.
In C# GC.Collect() "cleans up" the memory from unused/disposed objects.
For sure, there's no direct equivalent for that in Obj-C, but that may shed some light on your problem also (it could be memory-related).

Loading image in view takes appx 10-20 seconds on IPhone

I have created a app which pick image from Camera and on didFinishPickingMediaWithInfo pass this to another view and load this view. I think code is okay but it takes appx 15-20 seconds to display second view. So please let me know how can I fix this loading issue.
My code block is :
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[NSThread detachNewThreadSelector:#selector(switchToSecondView:) toTarget:self withObject:info];
}
-(void) switchToSecondView:(NSDictionary *)info
{
UIImage *image = [info
objectForKey:UIImagePickerControllerOriginalImage];
secController =[[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secController.myimage = image;
AppDelegate *appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navController pushViewController:secController animated:NO];
}
Thanks,
Laxmilal Menaria
UiKit is [overwhelmingly] safe to use on the main thread only. Your work in switchToSecindView: is happening on a background thread. Behaviour is therefore undefined.
Likely what's happening is that UIKit is failing to notice your changes until it happens to be doing some other processing.

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];

Passing UIImage to second view controller lags transition

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];
}

using UIImagepickerController cameraoverlayview to take picture?

i am using UIImagepickerController to take pictures from camera..i am using my own view over the camera view by using the cameraoverlayview property...i want to take a picture from camera when user clicks on a button in my custom view...i am using the following code
- (void)viewDidLoad {
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imagePickerController animated:YES];
imagePickerController.showsCameraControls=NO;
imagePickerController.cameraOverlayView = self.customView;
}
- (IBAction) takePicture
{
[imagePickerController takePicture];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissModalViewControllerAnimated:YES];
}
but when i run this code it gives me error
ERROR: FigCreateCGImageFromJPEG returned -12905. Input (null) was 773625 bytes.
and i also get warnings for memory use level 2 and then level 1
and no image is displayed in the imageView.. can anyone help me what i might be doing wrong??
btw i am using iPhone 3G with iOS4.1 installed on it
UIImagePickerControllerOriginalImage is a symbol (an NSString * constant) and you can't assume its value. Use as is, without quotes. Other than that, if you properly retain and create both the picker and the image view, it should work.