Search code examples
iosobjective-cxcodevideoavfoundation

iOS AVCaptureVideoPreviewLayer not showing in UIView?


The Problem

I have a sample application from Apple (SquareCam) that I'm using as reference to create a custom interface for a camera. I'm using the AVFoundation framework. If I build and run the project from Apple, the app runs as expected. However, if I take the same code from that project and place it in a new project in Xcode, the video preview will not display.

I have simplified the code down to the essential components to run a video preview layer. Again, this code runs fine as is in the Apple (SquareCam) project, but does not display in my new project.

The Code

- (void)setupAVCapture {
    NSError *error = nil;

    AVCaptureSession *session = [AVCaptureSession new];
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
        [session setSessionPreset:AVCaptureSessionPreset640x480];
    else
        [session setSessionPreset:AVCaptureSessionPresetPhoto];

    // Select a video device, make an input
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];

    if ([session canAddInput:deviceInput])
        [session addInput:deviceInput];

    previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    [previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
    CALayer *rootLayer = [previewView layer];
    [rootLayer setMasksToBounds:YES];
    [previewLayer setFrame:[rootLayer bounds]];
    [rootLayer addSublayer:previewLayer];
    [session startRunning];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupAVCapture];
}

What Have I Tried?

I have all of the outlets set up correctly. I have all of the framework libraries in my build phase. Both projects are using storyboard. What's odd is that I am able to capture an image from the camera and even switch the source from front to back. But the preview will not display. The Apple project was not setup with ARC. So, I updated the project to use ARC. Again, runs great in the Apple project, but not in a new project.

Thoughts?

Any ideas on what the issue could be? Is there a project setting that could cause this?


Solution

  • Had the same issue and the key was setting the AVCaptureVideoPreviewLayer's frame to the bounds of the UIView:

    // Setup camera preview image
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
    previewLayer.frame = _cameraPreview.bounds;
    [_cameraPreview.layer addSublayer:previewLayer];