我有一个启动AVCaptureSession来扫描条形码的按钮。除非您取消会话或扫描条形码并决定扫描另一个条形码,否则一切正常。为了再次启动它,视图控制器必须被解除然后再次呈现。
尝试再次启动会话时的错误在setUpCaptureSession()
中let captureSession = AVCaptureSession()
var captureDevice: AVCaptureDevice?
var captureLayer: AVCaptureVideoPreviewLayer?
以下是相关方法。
@IBAction func scanBarcode(sender: AnyObject) {
self.setupCaptureSession()
}
func cancel() {
NSNotificationCenter.defaultCenter().postNotificationName("backPressed", object: nil, userInfo: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
}
func cancelBarcodeScan() {
self.captureSession.stopRunning()
self.captureLayer?.removeFromSuperlayer()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "done")
self.navigationItem.leftBarButtonItem?.action = "cancel"
}
private func setupPreviewLayer(completion:() -> ()) {
self.captureLayer = AVCaptureVideoPreviewLayer(session: captureSession)
if let capLayer = self.captureLayer {
capLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
capLayer.frame = self.view.frame
self.view.layer.addSublayer(capLayer)
self.navigationItem.rightBarButtonItem = nil
self.navigationItem.leftBarButtonItem?.action = "cancelBarcodeScan"
completion()
} else {
self.showError("An error occured beginning video capture.")
}
}
private func addMetaDataCaptureOutToSession() {
let metaData = AVCaptureMetadataOutput()
self.captureSession.addOutput(metaData)
// metaData.metadataObjectTypes = metaData.availableMetadataObjectTypes
metaData.metadataObjectTypes = [AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode]
metaData.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
}
private func setupCaptureSession() {
self.captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let deviceInput: AVCaptureDeviceInput
do {
deviceInput = try AVCaptureDeviceInput(device: captureDevice)
} catch {
return
}
if (captureSession.canAddInput(deviceInput)) {
// Show live feed
captureSession.addInput(deviceInput)
self.setupPreviewLayer({
self.captureSession.startRunning()
self.addMetaDataCaptureOutToSession()
})
} else {
self.showError("Error while setting up input captureSession.")
}
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
for metaData in metadataObjects {
let decodedData: AVMetadataMachineReadableCodeObject = metaData as! AVMetadataMachineReadableCodeObject
upcTextField.text = decodedData.stringValue
itemNameTextField.text = decodedData.type
getProductData(decodedData.stringValue)
self.captureSession.stopRunning()
self.captureLayer?.removeFromSuperlayer()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "done")
self.navigationItem.leftBarButtonItem?.action = "cancel"
}
}
private func showError(error:String)
{
let alertController = UIAlertController(title: "Error", message: error, preferredStyle: .Alert)
let dismiss:UIAlertAction = UIAlertAction(title: "Ok", style: .Default, handler:{(alert:UIAlertAction!) in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
alertController.addAction(dismiss)
self.presentViewController(alertController, animated: true, completion: nil)
}
答案 0 :(得分:0)
我遇到了同样的问题,这就是我解决它的方法,我只是添加了一个 captureSession.stopRunning() captueSession.StartRunning()
if metadataObj.stringValue != nil {
// messageLabel.text = metadataObj.stringValue
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if supportedCodeTypes.contains(metadataObj.type) {
// 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?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
guard let url = URL(string: metadataObj.stringValue!) else {
return
}
if #available(iOS 10.0, *) {
performSegue(withIdentifier: "segue", sender: nil)
captureSession.stopRunning()
captureSession.startRunning()