Camera has incorrect screen placement when open fu

2019-02-20 20:22发布

问题:

I have an iPad app that has a popover (UIPopoverController) with a number of views pushed, one of which has a button that launches the camera... see image...

The camera is instigated with this method...

- (IBAction)selectPlanImageFromCamera:(id)sender
{
    [self.blockTextField resignFirstResponder];
    [self.levelTextField resignFirstResponder];
    [self.zoneNamePrefixTextField resignFirstResponder];
    [self.nameTextField resignFirstResponder];
    [self.notesTextView resignFirstResponder];

    imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.allowsEditing = NO;
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
    imagePicker.showsCameraControls = YES;

    [self presentViewController:imagePicker animated:YES completion:^{}];
}

I then get the fullscreen modal camera view displayed which all works as expect a part from the fact that it is positioned slightly lower than the screen bounds. This means that the controls at the bottom are 20px south of the screen and there is a 20px black band at the top of the screen... See image...

Whilst this app is now targeted at iOS6 I was getting the same effect previously with iOS5. Can anyone think of a workaround or fix?

Many thanks in advance, Michael.

回答1:

We suspected this was somehow related to the statusbar height, 20px. Our guess was right, and the below code worked for us which hides statusbar while UIIMagePickerController is shown.

 UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
 imagePicker.delegate = self;
 imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
 imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeImage,nil];
 imagePicker.allowsEditing = NO;

 if (IS_IPAD)
 {                
    imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

    [self presentViewController:imagePicker animated:YES completion:nil];
 }

One might have to add code below to each of the following delegates :- imagePickerControllerDidCancel, didFinishPickingMediaWithInfo and finishedSavingWithError.

if (IS_IPAD)
{
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
}


回答2:

Following the pointer from shawnwall's comment to the original question, I have managed to get this fixed by doing the presentViewController method call on the root UIViewController and then dismissing and re-establishing the UIPopoverController either side of taking the photo.

So, I have my method for instigating the camera view... (note two lines at the end are new - first line dismisses the popover and the second line presents the UIImagePickerController on main root UIViewController)

- (IBAction)selectPlanImageFromCamera:(id)sender
{
    [self.blockTextField resignFirstResponder];
    [self.levelTextField resignFirstResponder];
    [self.zoneNamePrefixTextField resignFirstResponder];
    [self.nameTextField resignFirstResponder];
    [self.notesTextView resignFirstResponder];

    cameraImagePicker = [[NonRotatingUIImagePickerController alloc] init];
    cameraImagePicker.allowsEditing = NO;
    cameraImagePicker.delegate = self;
    cameraImagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    cameraImagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
    cameraImagePicker.showsCameraControls = YES;

    [mainCanvasViewController.sitePopoverController dismissPopoverAnimated:YES];
    [mainCanvasViewController presentViewController:cameraImagePicker animated:YES completion:^{}];
}

I then re-present the popover anywhere that I am dismissing the UIImagePickerController - in this case on the didFinishPickingMediaWithInfo delegate method (in the same UIViewController as detailed above)...

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    if ([info objectForKey:UIImagePickerControllerMediaType] == (NSString *)kUTTypeImage)
    {
        ... // image handling
    }

    [picker dismissViewControllerAnimated:YES completion:^{}];

    UIBarButtonItem *tappedButton = mainCanvasViewController.navigationItem.leftBarButtonItem;
    [mainCanvasViewController.sitePopoverController presentPopoverFromBarButtonItem:tappedButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

This works fine - the closing of the camera view and re-presenting of the popover could be a bit neater as the popover reappears while the camera is animated out of the bottom of the screen, it would look nicer if the popover appeared after the camera transitioned away, but for me this is not a big issue at the moment.

Hope this helps someone who wants to open a fullscreen camera UIImagePickerController from a UIPopoverController.

Kind regards, Michael.



回答3:

Try

cameraImagePicker.modalPresentationStyle = UIModalPresentationFullScreen;

That will tell the UIImagePickerController instance the presentation style and fix this bug.