I have a UITabBarController which has 4 items tabs. One of them is an AvCaptureVideoPreviewLayer (is a barcode scanner). What I would like to do is to disable autorotate only for AVCaptureVideoPreviewLayer (like iOS camera app) but not for the item bar which would rotate with the screen. It is a bit difficult situation because I think that the UITabBarConrtoller doesn't allow you easily to disable rotation.
The code for my camera view is:
import UIKit
import AVFoundation
class ScannerViewController: UIViewController, 
// MARK: Properties
/// Manages the data flow from the capture stage through our input devices.
var captureSession: AVCaptureSession!
/// Dispays the data as captured from our input device.
var previewLayer: AVCaptureVideoPreviewLayer!
// MARK: Methods
override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = UIColor.blackColor()
    self.captureSession = AVCaptureSession()
    // This object represents a physical capture device and the properties associated with that device
    let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    // Is useful for capturing the data from the input device
    let videoInput: AVCaptureDeviceInput
    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        // TODO: maybe show an alert
        return
    }
    if (self.captureSession.canAddInput(videoInput)) {
        self.captureSession.addInput(videoInput)
    } else {
        failed();
        return;
    }
    let metadataOutput = AVCaptureMetadataOutput()
    if (self.captureSession.canAddOutput(metadataOutput)) {
        self.captureSession.addOutput(metadataOutput)
        metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code,
            AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,
            AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeCode93Code,
            AVMetadataObjectTypeCode128Code]
    } else {
        failed()
        return
    }
    // Adds the preview layer to display the captured data. Sets the videoGravity to AspectFill so that it covers the full screen
    self.previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession);
    self.previewLayer.frame = self.view.layer.bounds;
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    self.view.layer.addSublayer(previewLayer);
    self.captureSession.startRunning();
}
override func viewDidLayoutSubviews() {
    self.previewLayer?.frame = self.view.layer.bounds;
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if (self.captureSession.running == false) {
        self.captureSession.startRunning();
    }
}
override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if (self.captureSession.running == true) {
        self.captureSession.stopRunning();
    }
}
func failed() {
    let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .Alert)
    ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    presentViewController(ac, animated: true, completion: nil)
    self.captureSession = nil
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
    self.captureSession.stopRunning()
    if let metadataObject = metadataObjects.first {
        let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        foundCode(readableObject.stringValue);
    }
}
/// Completes some tasks when a barcode is found.
///
/// - parameter code: The the barcode found.
func foundCode(code: String) {
}
}
                I'm not 100% sure if I understand it correctly. But what you could do is:
1 - Subclass your UITabBarController and override shouldAutorotate with something like this:
override var shouldAutorotate: Bool {
    guard let viewController = tabBarController?.selectedViewController else { return false }
    return viewController.shouldAutorotate
}
This means that the selected UIViewController will define if it should autorotate.
2 - Now that the UITabBarController will ask its ViewControllers if it should autorotate, you have to override shouldAutorotate in every controller as well.
And that's it!
Sorry if I misunderstood your question. If you provide more information it would help.
Take care :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With