仅对AVCaptureVideoPreviewLayer禁用旋转

时间:2016-01-05 10:22:18

标签: ios swift uitabbarcontroller

我有一个UITabBarController,它有4个项目标签。其中一个是AvCaptureVideoPreviewLayer(是条形码扫描仪)。我想要做的是仅为AVCaptureVideoPreviewLayer(如iOS相机应用程序)禁用自动旋转,但不对于随屏幕旋转的item bar禁用自动旋转。这有点困难,因为我认为UITabBarConrtoller不允许您轻松禁用旋转。

我的相机视图的代码是:

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) {

}

}

1 个答案:

答案 0 :(得分:2)

我不能100%确定我是否理解正确。但你能做的是:

1 - 对您的UITabBarController进行子类化,并使用以下内容覆盖shouldAutorotate

override var shouldAutorotate: Bool {
    guard let viewController = tabBarController?.selectedViewController else { return false }
    return viewController.shouldAutorotate
}

这意味着所选的UIViewController将定义它是否应该自动旋转。

2 - 既然UITabBarController会询问其ViewControllers是否应该自动旋转,那么您也必须在每个控制器中覆盖shouldAutorotate

那就是它!

很抱歉,如果我误解了你的问题。如果您提供更多信息,这将有所帮助。

小心:)