2016-01-05 13 views
7

Mam UITabBarController, który ma 4 zakładki elementów. Jednym z nich jest AvCaptureVideoPreviewLayer (jest skanerem kodów kreskowych). Chciałbym tylko wyłączyć autorotate tylko dla AVCaptureVideoPreviewLayer (jak aplikacja aparatu iOS), ale nie dla item bar, które obracałoby się z ekranem. To jest trochę trudna sytuacja, ponieważ myślę, że UITabBarConrtoller nie pozwala na łatwe wyłączenie rotacji.Wyłącz obracanie tylko dla AVCaptureVideoPreviewLayer

Kod dla mojego widzenia kamery wynosi:

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

} 

} 

Odpowiedz

2

nie jestem w 100% pewien, czy rozumiem go poprawnie. Ale co można zrobić, to:

1 - Podklasa Twój UITabBarController i zastąpić shouldAutorotate coś takiego:

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

Oznacza to, że wybrany UIViewController będzie określić, czy powinna ona AutoRotate.

2 - Teraz, gdy UITabBarController poprosi swoich ViewControllers czy powinien AutoRotate, trzeba zastąpić shouldAutorotate w każdym kontrolerze, jak również.

I to wszystko!

Przepraszam, jeśli źle zrozumiałem twoje pytanie. Jeśli podasz więcej informacji, to pomoże.

Uważaj :)

+1

fajnie! Pomogło mi to –

Powiązane problemy