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.
Related
MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = #"bottle";
if ( water == nil )
water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
water.contentViewController = bottle;
This code runs once....when I click again on UITableViewCell my app crashes..
I am unable to figure it Out Why??
ERROR
-[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.'
NOTE When Change my code this to following it works:
MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = #"bottle";
if ( water == nil )
water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
water = [[UIPopoverController alloc] initWithContentViewController:bottle];
But i uses memory as double allocation is present.How can I resolve this
You are making a confusion between initialisation, presentation, and content modification of your UIPopoverController.
It is OK to store your popover on an instance variable, to avoid recreating it every time. It doesn't cause any trouble either to set the contentViewController to a new instance of "Bottle" if that "water" exists already.
But your error messages says it all: -[UIPopoverController setContentViewController:animated:] : you are trying to change the content of your popover with an animation. It means, your popover must already be presented (i.e. visible). For doing so, use one of the two methods starting with presentPopoverFrom... before changing its content.
In other words, only once your popover is presented, you can animate a change of content. Note also that it makes no sense to animate a change when your popover is not yet presented / visible. Use the setter .contentViewController = for that (or the non-animated method).
A note on your edit/note: Writing the same allocation in the two branches of the if/else clause is pointless. And it doesn't cause the system to use twice memory. Because when the compiler sees the second line ("else"...), it first releases the existing instance of the popovercontroller before allocating the new one and making the "water" instance variable point to it.
If you want to push then try this
MyVC *Newpage = [[MyVC alloc] initWithNibName:#"MyVC" bundle:nil];
[self.navigationController pushViewController:Newpage animated:YES];
If you want too go back from this page i.e pop then use this
You are using wrong code.
[self.navigationController popViewControllerAnimated:YES];
There is problem in hiding the popover view. Check if presented correctly.
if (popover == nil) {
popover = [[UIPopoverController alloc] initWithContentViewController: MYVC];
popover.delegate = self;
[self.tablesPopoverController presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Use delegate methods to check if popover is visible or not.
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
// do something now that it's been dismissed
}
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.
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.
My ipad project is master-detail view based. There is a button on detail view's toolbar, when user tap on the button, it popup a popover view to show four buttons (as menu). Three of buttons' actions are like the following (the three buttons show three different model form sheets):
- (void) showOnlineSgf
{
NSLog(#"showOnlineSgf");
TGOOnlineSgfViewController *dlg =
[[TGOOnlineSgfViewController alloc] initWithNibName:#"TGOOnlineSgfViewController"
bundle:nil];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:dlg];
[nav setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:nav animated:YES completion:nil];
dlg = nil;
nav = nil;
}
The other button's action is to show a MFMailComposeViewController. Code is like the following:
- (void) emailCurrentGame
{
NSLog(#"email current game");
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[self presentModalViewController:picker animated:YES];
picker = nil;
}
The weird behavior is that when I tap the button what should execute showOnlineSgf(), but emailCurrentGame() is actually executed. When I set a breakpoint in showOnlineSgf(), it's hit, and step by step, each statement in showOnlineSgf() is executed. But the result on screen is a MFMainComposeViewController shows up.
I know this question is hard to answer. Any idea is appreciated.
Check your outlet connection of your UIButton that triggers showOnlineSgf. Most likely you copy pasted your UIButton in Interface Builder, which causes it to copy its assigned action as well. Then you've connected your other action, resulting in your UIButton having two actions.
To resolve the problem, simply disconnect your UIButton that triggers showOnlineSgf from the emailCurrentGame action.
Sounds like you copy pasted in the interface builder an already connected button. Check if the button has more than one action assigned.