UIImagePickerControllerCameraDeviceFront works eve

2019-06-07 07:33发布

问题:

This question is very similar to an existing question asked here UIImagePickerControllerCameraDeviceFront only works every other time I tried the solution presented but it didn't work for me

I have a simplest of a project with two view controllers. In the blue one I am displaying a small UIView with a UIImagePickerController in it. NOTE: I am displaying front facing camera when app is launched.

I hit the next button and go to orange view controller and when I hit the back button and come back to blue view controller the UIImagePickerController flips from Front to rear. I guess the reason is that it thinks its busy and moves to the rear cam. If I keep moving back and forth between the view controllers the camera keeps flipping front, back, front, back, front, back...

Here is my code and screenshots, what am I doing wrong?

In my *.h

#import <UIKit/UIKit.h>

@interface v1ViewController : UIViewController <UIImagePickerControllerDelegate>
{
    UIImagePickerController *picpicker;
    UIView *controllerView;

}

@property (nonatomic, retain) UIImagePickerController *picpicker;
@property (nonatomic, retain) UIView *controllerView;

@end

In my *.m file (This code is only used when blue colored view controller is displayed)

#import "v1ViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>

@implementation v1ViewController

@synthesize picpicker;
@synthesize controllerView;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];


    picpicker = [[UIImagePickerController alloc] init];

    picpicker.delegate = self;
    picpicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
    picpicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    picpicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
    picpicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    picpicker.showsCameraControls = NO;
    picpicker.navigationBarHidden = NO;
    picpicker.wantsFullScreenLayout = NO;

    controllerView = picpicker.view;
    [controllerView setFrame:CGRectMake(35, 31, 250, 250)];

    controllerView.alpha = 0.0;
    controllerView.transform = CGAffineTransformMakeScale(1.0, 1.0);

    [self.view addSubview:controllerView];

    [UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionCurveLinear
                     animations:^{
                         controllerView.alpha = 1.0;
                     }
                     completion:nil
     ];

}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [picpicker dismissModalViewControllerAnimated:YES];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    [picpicker dismissModalViewControllerAnimated:YES];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}

@end

回答1:

You are dismissing the controller in both the viewDidDisappear and viewWillDisappear methods. That could be the cause of your problem.



回答2:

Although I do not have a device with a camera available right now to verify this, it seems that you're not dismissing the pickerview controller correctly. The documentation states that you should call dismissModalViewControllerAnimated: on the parent controller in order to dismiss the picker (though, calls to presented controllers will propagate to presenters - so this is not the problem), but in your case you're not displaying the controller modally in the first place so it will not work.

What I would try in this case is to release the picker instead (if not under ARC) and set it to nil (instead of calling [picpicker dismissModalViewControllerAnimated:YES];).

PS. In fact, it seems that there is a bigger problem with your design. Since each button is set to present the other party modally you are not dismissing any of the controllers ever. The controllers just keep stacking on each other. You should either consider to embed them in a navigation controller and have it handle the hierarchy or just set dismissModalViewControllerAnimated: (dismissViewControllerAnimated:completion: on iOS5+) as the action of the second controller's button instead of a modal segue.



回答3:

This is a very simple issue. I don't know why this happens exactly, but it seems that UIImagePickerController was designed to recreated each time it's needed instead of keeping any reference to it, which seems logical if you think about it. Basically, you need to recreate and reconfigure your picker each time. Below I've pasted some code to give an image of what I mean.

Simple solution:

- (UIImagePickerController *)loadImagePicker {
    UIImagePickerController *picpicker = [[UIImagePickerController alloc] init];
    picpicker.delegate = self;
    picpicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
    picpicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    picpicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
    picpicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
    picpicker.showsCameraControls = NO;
    picpicker.navigationBarHidden = NO;
    picpicker.wantsFullScreenLayout = NO;
    return picpicker;
}

and in:

-(void)viewWillAppear:(BOOL)animated{
    if(!self.picpicker){
        self.picpicker = [self loadImagePicker];
        [self.view addSubview: self.picpicker];
    }
}

-(void)viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
     [self.picpicker removeFromSuperview];
     self.picpicker = nil;
}