Search code examples
iosobjective-ccamerauinavigationcontrolleravcapturesession

Camera feed get stuck when navigate back - ios, objective-c


I have developed an iOS application in which there is a camera to take pictures. I have used AVCaptureSession to implement the camera and it works fine. Then I added a UINavigationController to go to the preview view (view which contains taken photos) and came back to the camera view. Navigation works without any problem and the thing is when I came back to the camera view, camera feed doesn't work any more, it is stuck. Can someone please help me to fix this. I have attached my code and an image of the storyboard, with this.

Piece of code I used to implement the camera feed

@implementation CameraViewController{

    UIView *view_cameraFeed;

    AVCaptureSession *session;

    AVCaptureStillImageOutput *stillImageOutput;

}

- (void)viewDidLoad {

    [super viewDidLoad];

    view_cameraFeed = [[UIView alloc]initWithFrame:CGRectMake(X,Y, WIDTH,HEIGHT)];

    [self.view addSubview:view_cameraFeed];
}

- (void)viewWillAppear:(BOOL)animated{

    session = [[AVCaptureSession alloc] init];

    [session setSessionPreset:AVCaptureSessionPresetPhoto];

    AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    NSError *error;

    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];

    if ([session canAddInput:deviceInput]) {

        [session addInput:deviceInput];
    }

    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];

    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    CALayer *rootLayer = self.view.layer;

    [rootLayer setMasksToBounds:YES];

    CGRect frame = view_cameraFeed.frame;

    [previewLayer setFrame:frame];

    [rootLayer insertSublayer:previewLayer atIndex:0];

    stillImageOutput = [[AVCaptureStillImageOutput alloc] init];

    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey,nil];

    [stillImageOutput setOutputSettings:outputSettings];

    [session addOutput:stillImageOutput];

    [session startRunning];
}

Piece of code used to navigate to the preview view

 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

 UIViewController *CameraPreviewViewController = [storyboard instantiateViewControllerWithIdentifier:@"CameraPreviewViewController"];

[self.navigationController pushViewController:CameraPreviewViewController animated:YES];

Piece of code used to come back to the camera feed view

[self.navigationController popViewControllerAnimated:YES];

This is my storyboard

enter image description here


Solution

  • Finally I found a way to get this problem solved. Sorry for being delayed to post the answer.

    If we do initialising the session and rest of the things(except "[session startRunning]") in viewWillAppear,those steps will run more than once when we navigating back to the view. Thats why it gets stuck.

    I just moved all the lines in viewWillAppear except "[session startRunning]" to viewDidLoad. So that those lines will run only once.

    This solved my problem and this is the working code.

    Piece of code I used to implement the camera feed

    @implementation CameraViewController{
    
        UIView *view_cameraFeed;
    
        AVCaptureSession *session;
    
        AVCaptureStillImageOutput *stillImageOutput;
    
    }
    
    - (void)viewDidLoad {
    
        [super viewDidLoad];
    
        view_cameraFeed = [[UIView alloc]initWithFrame:CGRectMake(X,Y, WIDTH,HEIGHT)];
    
        [self.view addSubview:view_cameraFeed];
    
        session = [[AVCaptureSession alloc] init];
    
        [session setSessionPreset:AVCaptureSessionPresetPhoto];
    
        AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
        NSError *error;
    
        AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
    
        if ([session canAddInput:deviceInput]) {
    
            [session addInput:deviceInput];
        }
    
        AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    
        [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    
        CALayer *rootLayer = self.view.layer;
    
        [rootLayer setMasksToBounds:YES];
    
        CGRect frame = view_cameraFeed.frame;
    
        [previewLayer setFrame:frame];
    
        [rootLayer insertSublayer:previewLayer atIndex:0];
    
        stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    
        NSDictionary *outputSettings = [[NSDictionary alloc]     initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey,nil];
    
        [stillImageOutput setOutputSettings:outputSettings];
    
        [session addOutput:stillImageOutput];
    }
    
    - (void)viewWillAppear:(BOOL)animated{
    
        [session startRunning];
    }
    

    All the other codes are same as in the question