Using the following code:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!self.alreadyAppeared) {
[self performSelector:#selector(showCamera) withObject:nil afterDelay:0.3];
}
}
-(void)showCamera
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.showsCameraControls = YES;
picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
picker.delegate = self;
[self presentViewController: picker animated:YES completion:NULL];
}
my app works perfectly. However if I change the
picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
to
picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
I lose the image. The following code is how I capture the image and set an imageview within my app. I use a Nav controller to return to the app:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
self.cf.imageView.image = chosenImage;
NSLog(#"%#",chosenImage);
[picker dismissViewControllerAnimated:YES completion:NULL];
// pop back to previous controller
NSArray *myControllers = self.nc.viewControllers;
int previous = (int)myControllers.count - 2;
UIViewController *previousController = [myControllers objectAtIndex:previous];
[self.nc popToViewController:previousController animated:YES];
}
Again, this works just fine on my iPad and it works just fine using the front camera. Even when using the rear camera the chosen image (that I log) appears correct. Does anybody have any idea why the rear camera setting would have such an effect?
One other item: I get this very irritating message that has about 1,000 different explanations none of which get rid of the message:
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
When using the iPhone 6 and 6 plus, you must prevent your views from reloading each time you navigate away from the camera control (picker). My app uses a View Controller that creates a dynamic view which is a form. Each field on that form is pulled from a web service and becomes a subview of the form. That includes the camera field, which I use a viewcontroller and xib to build the field. The form view builds the entire form through a drawRect method. The camera field attempts to call that method each time it navigates away. I prevent it from reloading and that appears to have solved the issue.
A more standard app may create the camera field dynamically in viewDidAppear method of the main view controller. If you have the main view controller set as the delegate for the camera field, it will still call the viewDidAppear when it navigates away from the picker. That must be prevented or you will lose the image.
The really funny thing here is that this only happens on iPhone 6 and 6 plus. All other devices do not attempt to reload the views ... go figure.
Related
I'm creating custom overlay view for video recording.
I've add a button to start/stop recording:
[takePhotoBut addTarget:imagePickerController action:#selector(toogleRecord:) forControlEvents:UIControlEventTouchUpInside];
which calls [super startVideoCapture]; or [super stopVideoCapture]; in my custom UIImagePickerController. Also I've set delegate
CustomPickerController *imagePickerController= [[CustomPickerController alloc]init];
imagePickerController.allowsEditing = NO;
imagePickerController.delegate = self;
and I expect to get notified about imagePickerController:didFinishPickingMediaWithInfo:, but I get no response. I believe it happens, because ios wait till user clicks "Use video". But I want to get notified without user clicking that button. Are there any workarounds??
EDIT 1
the way I'm presenting ImagePicker:
[self presentViewController:imagePickerController animated:YES completion:nil];
It is not property on my VC.
Check whether your imagePickerController cameraCaptureMode set to UIImagePickerControllerCameraCaptureModeVideo
imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
This solves my issue.
I had the same issue. Fixed it by hiding the camera controls.
imagePickerController.showsCameraControls = NO;
I am using a regular UIImagePickerController to capture photo using the device camera. Following is the code I am using to create the UIImagePickerController,
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
self.imagePickerController.allowsEditing = NO;
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
self.imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
self.imagePickerController.delegate = self;
and following is the code that I am using to display the UIImagePickerController
[self presentViewController:self.imagePickerController animated:YES completion:nil];
Now, when the UIImagePickerController is presented, if I zoom to capture and come back to my presenting view controller, the app crashes irregularly with BAD_ACCESS. After editing the scheme and some debugging, I see the following error,
-[PLImagePickerCameraView didHideZoomSlider:]: message sent to deallocated instance 0x140109400
It seems that the zoom slider delegate is called on an unallocated instance. Anyone else observed this behaviour? I am using working on iOS 8.1 and testing it on iPhone 5S. The search for PLImagePickerCameraView doesn't yield much. Any insights would be really helpful before I decide to go with custom Picker.
I experienced the UIImagePickerController zoom crash, as well. Adding a delay fixed most, but not all, of the crashes.
The root cause is the controller attempting to callback to a delegate after the delegate has been deallocated. I ended up implementing a subclassed UIImagePickerController to remove the delegate of the slider view.
You can find some sample code I posted on a similar question.
I have a custom UITableViewCell declared thusly:
#interface ValveCell : UITableViewCell <UINavigationControllerDelegate,UIImagePickerControllerDelegate>
A button which hooks to the following method:
- (void) addPicture {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
// I have tried every possible value for the presentation style
picker.modalPresentationStyle = UIModalPresentationNone;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// controller is a #property I added to my custom class
// it is the UIViewController that is the data source/delegate for the table view
[self.controller presentViewController: picker animated: YES completion: nil];
}
And the supporting delegate method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion: nil];
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
if (chosenImage) {
[self.valve pushPhoto: chosenImage];}
}
There are two issues (at least) I'm having with this code:
Every time I click the button, I get the following warning in my transcript: "Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates." I've tried the various presentation styles. I don't know why this is happening, or what I need to do to make it go away.
It bothers me that I have to hand a controller to the cell (in my tableView:cellForRowAtIndexPath: method). I know walking the superView chain is frowned upon. Is there a no better way to get a controller to open it from? Or an alternate way of opening the picker that doesn't need a controller? Even something like self.tableView.delegate would work if cells but had a back pointer to their tableview.
UPDATE
Answer for #1 goes to #Jiten Parmar below. As for #2, I found the PPTopMostController pod which allowed me to use the code:
[UIViewController topMostController]
which worked like a charm.
"Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates."
The answer is that when your app is in the portrait mode and you open the image picker with landscape it will show this warning in the console, but no need to worry that, it is not critical for your app and no crash issue will be there.
On a communityapp development, I have the task of making an iPhone app into an iPad app.
Following the documentation, I used the following code to spawn my camera view :
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.delegate = self;
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
self.imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
self.imagePickerController.allowsEditing = YES;
self.imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
}
popover = [[UIPopoverController alloc] initWithContentViewController:self.imagePickerController];
[popover presentPopoverFromRect:self.profilePicture.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
return;
}
But when spawned, I get this annoying "extra ghostly" camera button...
It doesn't work, and seems only to taunt me.
If I ask the object to hide its input buttons, ALL buttons disappear. I see no way of being able to tell that specific button to sod off.
UPDATE
I discovered it's only there the first time. If I close and reopen the popover, it's gone...
Sadly, this appears to be a bug in iOS 6 itself. There are a few possible workarounds, however.
You can set the showsCameraControls property of the image picker to false. This will remove the ghostly image, but, the other controls will be removed as well. You'll have to write your own view with buttons and whatnot to call the correct actions.
You say if you close and reopen the popover, the button goes away. It may be possible for you to set the showsCameraControls property of the picker to false, and then back to true before the picker is displayed. If it doesn't work, try creating a sort-of fake open/close action when the picker is initialized.
I'm having a very strange behavior:
in iOS 5 I present UIImagePickerController in this way:
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
imagePicker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:imagePicker animated:YES];
now in iOS 6 this produce a crash. I resolved the crash by writing a category on UIImagePickerController:
#implementation UIImagePickerController (NonRotating)
- (BOOL)shouldAutorotate
{
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#end
The problem is that now the UIImagePickerController doesn't rotate and it's shown up-side. Moreover, when I press the "cancel" button and the picker is dismissed, the app crash again.
If I use the UIImagePickerController inside a UIPopoverController, all works fine (belonging to the fact that the popover doesn't rotate) but when I dismiss the popover ALL view controller in my app stop responding to rotation events and this cause that all app is blocked in this orientation. To restore the correct behavior I need to quit the app from the background and open again.
This is the code I'm using to display popover
_cameraPopoverController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[_cameraPopoverController presentPopoverFromRect:_takeFromCamera.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
This problem drive me crazy !
What is your picker source type?
Photo library/album or camera roll?
Assuming that you are using Photo Library / Album source, on iPad, you MUST use a popover:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html (look in the overview, point 4)
presenting it fullscreen is not supported.
About the other issue (after dismissing the popOver, the other VC's stops rotating) check that you have a STRONG reference to your popover (strong property).
Paste the code you are using to present the popover.
While I don't recommend using the category to override the image picker's default behavior, there is a bug in the implementation that causes the crash mentioned:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
~~~~
}
The return value shouldn't be an orientation mask, it should be an orientation, e.g. UIInterfaceOrientationPortrait.