iosavfoundationavcapturesessionavcapturedevice

Preventing AVCaptureVideoPreviewLayer from rotating, but allow UI layer to rotate with orientation


I have two view controllers. One is the root VC and contains the UI interface such as the record button. On this view controller, I also display the view of another VC at index 0. This view contains a AVCaptureVideoPreviewLayer.

I would like my video camera to mimic the Apple video camera app, where the interface layout adjusts with the rotation, but the video preview layer does not. You can see how the recording timer (UILabel) in the stock video app disappears and reappears at the top depending on the orientation.

Any idea how to do this? I found one suggestion that recommendeds adding the preview to the app delegate's window, since it won't conform to the rotation of the nav controller, but it didn't work for me.

Thanks!


Solution

  • Make sure to set shouldAutorotate to return false:

    -(BOOL)shouldAutorotate{
        return NO;
    }
    

    register for Notifications that orientation changed:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];
    

    implement the notification change

    -(void)orientationChanged:(NSNotification *)notif {
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
    
    // Calculate rotation angle
    CGFloat angle;
    switch (deviceOrientation) {
        case UIDeviceOrientationPortraitUpsideDown:
            angle = M_PI;
            break;
        case UIDeviceOrientationLandscapeLeft:
            angle = M_PI_2;
            break;
        case UIDeviceOrientationLandscapeRight:
            angle = - M_PI_2;
            break;
        default:
            angle = 0;
            break;
    }
    
    
    }
    

    and rotate the UI

     [UIView animateWithDuration:.3 animations:^{
            self.closeButton.transform = CGAffineTransformMakeRotation(angle);
            self.gridButton.transform = CGAffineTransformMakeRotation(angle);
            self.flashButton.transform = CGAffineTransformMakeRotation(angle);
        } completion:^(BOOL finished) {
    
    }];
    

    This is how I implement the screen being locked but rotating the UI, if this works link the stacks post and I can copy it over there and you can tick it :P