UIImagePickerController really slow when calling alloc init - ios

I have a view controller that is presented on pressing on one of the tabs in a tabBarController. In this view controller I initialise a UIImagePickerController in the viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
//Set imagePicker
//-------------------------//
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
_imagePicker.videoMaximumDuration = 10.0f;
}
The intention is to then display the UIImagePickerController at a later time when a button is pressed. For some reason though when the tab icon is pressed for this view controller, there is a 3-4 second hang while this viewDidLoad method is running. When I comment out the line _imagePicker = [[UIImagePickerController alloc] init] there is no hang time and the view controller loads immediately - as it should.
Does anyone know why allocating and initialising the UIImagePickerController is taking so long? If so, is there a way to speed it up other than running it as a background process? It seems like this is not normal behaviour.
I am using iOS7, and I am not calling viewWillAppear or viewDidAppear.

Turns out this is only a problem when in debug mode (when the iPhone is connected and running through Xcode). Once the same app is running without being connected to Xcode the lag doesn't occur.

Try this iOS 12
//show a HUD or activityIndicator
dispatch_async(dispatch_queue_create("openPhotosCamera", NULL), ^{
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
//hide HUD or activityIndicator
[presenter presentViewController:mediaUI animated:YES completion:nil];
});
});
**presenter is yourViewController / self

Try this.
- (void)viewDidLoad{
//Set imagePicker
//-------------------------//
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
_imagePicker.videoMaximumDuration = 10.0f;
[super viewDidLoad];

Related

cameraOverlayView of UIImagePickerController disappears immediately

My Storyboard contains a CameraViewController in which I designed my custom overlay view.
As long as I use it as one tab of my UITabbarController, the cameraOverlayView is visible. But if I segue to this view controller from any other VC, the overlay view is visible only for a fraction of a second, then only the preview image is visible.
#implementation CameraViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIImagePickerController *picker = [UIImagePickerController new];
if (![UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) return;
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.showsCameraControls = NO;
picker.allowsEditing = NO;
picker.cameraOverlayView = self.view;
[self presentViewController:picker animated:YES completion:nil];
}
I have tried any segue types, presentation styles, etc., the problem stays the same.
I inserted some logs in viewDidDisappear, and noticed that this function in fact is called, I guess that's the reason why the overlay disappears.
Keep in mind: If I just open the tab of my Tabbarcontroller, everything just works fine! The problem only occurs if I segue to the CameraVC.
Thanks in advance!
The solution is to select modal presentation style and "Over current context", because then the viewDidDisappear event is not triggered.

UIPopoverController not triggering delegate methods

I'm trying to detect when a UIPopoverController gets dismissed, but it seems not to work properly, the methods are not getting called. This is my code for presenting the UIPopoverController:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
UIPopoverController *popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
popoverVC.delegate = self;
[popoverVC presentPopoverFromRect:CGRectMake(self.frame.origin.x,self.frame.origin.y, self.frame.size.width, self.frame.size.height) inView:[home view] permittedArrowDirections:0 animated:YES];
I'm trying to fire this method, but is not getting called:
- (void) popoverControllerDidDismissPopover:(UIPopoverController *) popoverController;
And I'm indeed adding the delegate to the header:
#interface Map : UIView <UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate, UIScrollViewDelegate,UIPopoverControllerDelegate>
I don't know what I'm missing out, is not working at all.
You probably already solved it, but I just faced the same problem. I'm holding a instance of UIPopoverController in my Viewcontroller and had it this way:
self.popover.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:wgtvc];
of course this doesn't work because I'm initializing the UIPopoverController AFTER setting the delegate, which overrides the delegate setting. So the correct way is to FIRST initialize the UIPopovercontroller and THEN setting the delegate
self.popover = [[UIPopoverController alloc] initWithContentViewController:wgtvc];
self.popover.delegate = self;
Maybe you are reinitializing your UIPopoverController somewhere - just set the delegate again after reinitializing.
Hpoe this helps.
So, I figured out how to make it work.
I made a "global" variable for the class.
self.popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
self.popoverVC.delegate = self;
Because it's an UIImagePickerController inside a UIPopoverController, I needed to listen to the UIImagePickerController for dismission too and combine both methods:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
- (void) popoverControllerDidDismissPopover:(UIPopoverController *) popoverController
So I can now detect when the UIPopoverController gets dismissed.

How to init an object when a controller appears without blocking the UI with GCD

In my app I need to show a UIImagePickerController when a button is tapped. Here is the code I used in the method called by the button on the controller when it gets pressed:
- (IBAction)choosePressed:(id)sender {
if (!self.pickerController) self.pickerController = [[UIImagePickerController alloc]init];
self.pickerController.delegate = self;
self.pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self.navigationController presentViewController:self.pickerController animated:YES completion:nil];
}
Problem is that UIImagePickerControllers are very slow to load, so I thought that moving the initialization of the picker in the viewDidAppear:animated method, possibly in another thread, would have been a good way to fasten the process of creation/showing of the picker so I did this:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
dispatch_queue_t myQueue = dispatch_queue_create("Picker Queue", NULL);
dispatch_async(myQueue, ^{
self.pickerController = [[UIImagePickerController alloc]init];
self.pickerController.delegate = self;
});
}
- (IBAction)choosePressed:(id)sender {
self.pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self.navigationController presentViewController:self.pickerController animated:YES completion:nil];
}
With this the pickerController shows up immediately when the button is pressed but when the main controller is loaded the UI freezes for a little bit (probably because of the initializzation of the pickerController) but the init should be done in another thread since I used the dispatch_async mechanism shouldn't it? Is there any mistake in my code?
I'm very new to GCD so I must be missing something!
It's a misuse of UIKit to access it from a background thread. You could perhaps show a "loading..." screen briefly. I think the best policy is to not worry about it.

iOS 4.2 - dismissModalViewControllerAnimated method recalling ViewDidLoad

I am working with camera in my application. Here are steps how I am working.
1) In MyViewController, I am opening an ActionSheet.
2) On tap a button in that Action sheet opening camera using following code
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.allowsEditing = YES;
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
3) After taking a Photo and tapping on USE following code get executed
// I use the caputred photo
[ self dismissModalViewControllerAnimated:YES];
After this statement its calling "ViewDidLoad" of MyViewController, which is actually refreshing my screen, I dont want this behaviour.
This problem observed only on iOS 4.2
I am using ARC
Please help me if any one has already faced this issue...

How do I implement a UIImagePickerController with a TabBarController

I have been beating my head on this for a few hours. I have some sample code (using a UINavigationController) when the view loads the camera roll will be presented. However, when I try to incorporate the same code into my app, which has a tabBarController, I get a blank modal UIImagePickerController. I didn't track down what I am doing wrong.
// bring up image picker
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
NSLog(#"UIImagePickerControllerSourceTypePhotoLibrary available");
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
ipc.allowsEditing = YES;
[self.tabBarController presentModalViewController:ipc animated:YES];
[ipc release];
}
Any insight would be appreciated.
Not sure what has changed, but this is possible by calling presentViewController from your tabBarController. This is the standard now and ensures your camera or image picker always gets presented as a full screen modal view.
For reference: presentViewController

Resources