swift - 使用带有 Swift2 的相机的黑色背景图像

标签 swift avfoundation swift2 ios9

我正在尝试使用 AVFoundation 显示用户摄像头(后置摄像头),但我一定是做错了什么,因为它只显示黑色背景图像。

我已经检查了我的隐私 > 相机,但我的应用程序没有关于相机的任何选项,而且我无法显示 .Alert 操作来询问用户访问相机的权限。

这是我的代码,我希望你能帮助我,因为这很奇怪:

import UIKit
import AVFoundation

class CodigoBarrasViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

@IBOutlet weak var messageLabel:UILabel!
@IBOutlet weak var imagenFondo:UIImageView!

@IBOutlet weak var BackgroundView:UIView!

var string:String!

var captureSession:AVCaptureSession?
var videoPreviewLayer:AVCaptureVideoPreviewLayer?
var qrCodeFrameView:UIView?

// Added to support different barcodes
let supportedBarCodes = [AVMetadataObjectTypeQRCode, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeUPCECode, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeAztecCode]

override func viewDidAppear(animated: Bool) {
    captureSession?.startRunning()
    self.qrCodeFrameView?.hidden = true
}

override func viewDidLoad() {

    //captureSession?.startRunning()

    super.viewDidLoad()

    // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video
    // as the media type parameter.
    let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    do {
        input = try AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
    }
    catch let error as NSError {
        print(error)
    }

    // Initialize the captureSession object.
    captureSession = AVCaptureSession()
    // Set the input device on the capture session.
    captureSession?.addInput(input)
    //captureSession?.addInput(input as AVCaptureInput)

    // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
    let captureMetadataOutput = AVCaptureMetadataOutput()
    captureSession?.addOutput(captureMetadataOutput)

    // Set delegate and use the default dispatch queue to execute the call back
    captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
    captureMetadataOutput.metadataObjectTypes = supportedBarCodes

    // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    videoPreviewLayer?.frame = view.layer.bounds
    view.layer.addSublayer(videoPreviewLayer!)

    // Start video capture.
    captureSession?.startRunning()

    // Move the message label to the top view
    view.bringSubviewToFront(imagenFondo)
    view.bringSubviewToFront(messageLabel)
    view.bringSubviewToFront(BackgroundView)

    // Initialize QR Code Frame to highlight the QR code
    qrCodeFrameView = UIView()
    qrCodeFrameView?.layer.borderColor = UIColor(hex: 0x00B7BB).CGColor
    qrCodeFrameView?.layer.borderWidth = 2
    view.addSubview(qrCodeFrameView!)
    view.bringSubviewToFront(qrCodeFrameView!)
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    //self.navigationController?.hidesBarsOnSwipe = true
    self.navigationController?.setNavigationBarHidden(true, animated: false)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {

    // Check if the metadataObjects array is not nil and it contains at least one object.
    if metadataObjects == nil || metadataObjects.count == 0 {
        qrCodeFrameView?.frame = CGRectZero
        //messageLabel.text = "No QR code is detected"
        return
    }
    else
    {
        // Get the metadata object.
        let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

        // Here we use filter method to check if the type of metadataObj is supported
        // Instead of hardcoding the AVMetadataObjectTypeQRCode, we check if the type
        // can be found in the array of supported bar codes.
        if supportedBarCodes.filter({ $0 == metadataObj.type }).count > 0 {
            // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
            let barCodeObject = videoPreviewLayer?.transformedMetadataObjectForMetadataObject(metadataObj as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
            qrCodeFrameView?.frame = barCodeObject.bounds

            if metadataObj.stringValue != nil {
                captureSession?.stopRunning()
                self.qrCodeFrameView?.hidden = false
                launchApp(metadataObj.stringValue)
            }
        }
    }


}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "seeProduct" {
        let destinationController = segue.destinationViewController as! ProductoCamViewController
        let string = (sender as! String!)

        let backItem = UIBarButtonItem()
        backItem.title = " "
        navigationItem.backBarButtonItem = backItem

        destinationController.ean = string
    }
}

func launchApp(decodedURL: String) {

    let alertPrompt = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
    //let alertPrompt = UIAlertController(title: "", message: decodedURL, preferredStyle: .ActionSheet)

    let confirmAction = UIAlertAction(title: "See product", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
        self.performSegueWithIdentifier("seeProduct", sender: decodedURL)
    })

    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
        self.captureSession?.startRunning()
        self.qrCodeFrameView?.hidden = true
    })

    //let cancelAction = UIAlertAction(title: "Cancelar", style: UIAlertActionStyle.Cancel, handler: nil)

    alertPrompt.addAction(confirmAction)
    alertPrompt.addAction(cancelAction)

    self.presentViewController(alertPrompt, animated: true, completion: nil)

}
}

提前致谢

问候。

最佳答案

如果您想访问相机,我建议您看一下 UIImagePickerControllerDelegate。

执行此操作,所有权限警报都会为您处理

关于swift - 使用带有 Swift2 的相机的黑色背景图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32973386/

相关文章:

ios - 如何使用 Xcode UITests 点击特定点

Swift,自定义单元格颜色不适用于披露指示器

ios - 在 Swift 中截图并在顶部添加文本/水印

iphone - 检测 AVFoundation 相机何时完成对焦

iphone - AVAssetExportSession dealloc 在 iOS 4.3 中崩溃

ios - 单击按钮时 UITextField 不会结束编辑(委托(delegate) textFieldDidEndEditing)

swift2 - 带有 Swift 2.0 的 Alamofire Manager 被取消

ios - 快速比较两个数组并删除具有不匹配的特定字段的元素

ios - 标签打印可选()即使强制展开

objective-c - AVComposition 的 AVPlayer 播放速率