2015-07-01 98 views
7

我在我的應用程序中使用條碼掃描。檢測到條碼後,我停止捕獲會話以允許處理條形碼。但是,在處理條形碼之後,我希望掃描控制器保持不變,並掃描下一個條形碼。我假設開始捕獲會話(startRunning())會做,但圖像保持凍結。我怎樣才能再次開始捕捉會話?iOS Swift條碼讀取

+0

條碼SCANER:https://iosdevcenters.blogspot.com/2017/09/building-barcode-and-qr- code-reader-in.html –

回答

11

停止會話使用此代碼

  self.session.stopRunning() 

首先它agian,使用此代碼

self.session.startRunning() 

這裏是所有實現條形碼掃描儀的代碼...

import UIKit 
import AVFoundation 


class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    let session   : AVCaptureSession = AVCaptureSession() 
    var previewLayer : AVCaptureVideoPreviewLayer! 
    var highlightView : UIView = UIView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Allow the view to resize freely 
     self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
      UIViewAutoresizing.FlexibleBottomMargin | 
      UIViewAutoresizing.FlexibleLeftMargin | 
      UIViewAutoresizing.FlexibleRightMargin 

     // Select the color you want for the completed scan reticle 
     self.highlightView.layer.borderColor = UIColor.greenColor().CGColor 
     self.highlightView.layer.borderWidth = 3 

     // Add it to our controller's view as a subview. 
     self.view.addSubview(self.highlightView) 


     // For the sake of discussion this is the camera 
     let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

     // Create a nilable NSError to hand off to the next method. 
     // Make sure to use the "var" keyword and not "let" 
     var error : NSError? = nil 


     let input : AVCaptureDeviceInput? = AVCaptureDeviceInput.deviceInputWithDevice(device, error: &error) as? AVCaptureDeviceInput 

     // If our input is not nil then add it to the session, otherwise we're kind of done! 
     if input != nil { 
      session.addInput(input) 
     } 
     else { 
      // This is fine for a demo, do something real with this in your app. :) 
      println(error) 
     } 

     let output = AVCaptureMetadataOutput() 
     output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
     session.addOutput(output) 
     output.metadataObjectTypes = output.availableMetadataObjectTypes 


     previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(session) as! AVCaptureVideoPreviewLayer 
     previewLayer.frame = self.view.bounds 
     previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
     self.view.layer.addSublayer(previewLayer) 

     // Start the scanner. You'll have to end it yourself later. 
     session.startRunning() 

    } 

    // This is called when we find a known barcode type with the camera. 
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

     var highlightViewRect = CGRectZero 

     var barCodeObject : AVMetadataObject! 

     var detectionString : String! 

     let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
      AVMetadataObjectTypeCode39Code, 
      AVMetadataObjectTypeCode39Mod43Code, 
      AVMetadataObjectTypeEAN13Code, 
      AVMetadataObjectTypeEAN8Code, 
      AVMetadataObjectTypeCode93Code, 
      AVMetadataObjectTypeCode128Code, 
      AVMetadataObjectTypePDF417Code, 
      AVMetadataObjectTypeQRCode, 
      AVMetadataObjectTypeAztecCode 
     ] 


     // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
     for metadata in metadataObjects { 

      for barcodeType in barCodeTypes { 

       if metadata.type == barcodeType { 
        barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

        highlightViewRect = barCodeObject.bounds 

        detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

        self.session.stopRunning() 

self.alert(detectionString) 
        break 
       } 

      } 
     } 

     println(detectionString) 
     self.highlightView.frame = highlightViewRect 
     self.view.bringSubviewToFront(self.highlightView) 

    } 



    func alert(Code: String){ 
     let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

     // for alert add .Alert instead of .Action Sheet 


     // start copy 

     let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 


      { 
       (alertAction:UIAlertAction!) in 


       // action when pressed 

       self.session.startRunning() 




     }) 

     actionSheet.addAction(firstAlertAction) 

     // end copy 






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

    } 



} 
+0

如果這個工作,不要忘了標記這個答案是正確的。 –

+0

我在做的事情幾乎是一樣的,但我有兩行代碼交換。我將結果字符串發送到我的處理程序,然後停止會話。它不會重新啓動。如果我在將結果發送給我的處理程序之前停止了會話,那麼它就工作了。 –

+0

在此處添加了Swift 3版本:http://stackoverflow.com/a/41512546/2108523 – mkhoshpour

10

編輯了swift 2.0的上述代碼:

import UIKit 
import AVFoundation 


class BarCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    let session   : AVCaptureSession = AVCaptureSession() 
    var previewLayer : AVCaptureVideoPreviewLayer! 
    @IBOutlet weak var highlightView: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Allow the view to resize freely 
//  self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
//   UIViewAutoresizing.FlexibleBottomMargin | 
//   UIViewAutoresizing.FlexibleLeftMargin | 
//   UIViewAutoresizing.FlexibleRightMargin 
//   
     // Select the color you want for the completed scan reticle 
     self.highlightView.layer.borderColor = UIColor.greenColor().CGColor 
     self.highlightView.layer.borderWidth = 3 

     // Add it to our controller's view as a subview. 
     self.view.addSubview(self.highlightView) 


     // For the sake of discussion this is the camera 
     let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

     // Create a nilable NSError to hand off to the next method. 
     // Make sure to use the "var" keyword and not "let" 
     var error : NSError? = nil 
     var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
     do { 
      input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
     } catch let myJSONError { 
      print(myJSONError) 
     } 

     // If our input is not nil then add it to the session, otherwise we're kind of done! 
     if input != AVCaptureDeviceInput() { 
      session.addInput(input) 
     } 
     else { 
      // This is fine for a demo, do something real with this in your app. :) 
      print(error) 
     } 

     let output = AVCaptureMetadataOutput() 
     output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
     session.addOutput(output) 
     output.metadataObjectTypes = output.availableMetadataObjectTypes 


     previewLayer = AVCaptureVideoPreviewLayer(session: session) 
     previewLayer.frame = self.view.bounds 
     previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
     self.view.layer.addSublayer(previewLayer) 

     // Start the scanner. You'll have to end it yourself later. 
     session.startRunning() 

    } 

    // This is called when we find a known barcode type with the camera. 
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

     var highlightViewRect = CGRectZero 

     var barCodeObject : AVMetadataObject! 

     var detectionString : String! 

     let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
      AVMetadataObjectTypeCode39Code, 
      AVMetadataObjectTypeCode39Mod43Code, 
      AVMetadataObjectTypeEAN13Code, 
      AVMetadataObjectTypeEAN8Code, 
      AVMetadataObjectTypeCode93Code, 
      AVMetadataObjectTypeCode128Code, 
      AVMetadataObjectTypePDF417Code, 
      AVMetadataObjectTypeQRCode, 
      AVMetadataObjectTypeAztecCode 
     ] 


     // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
     for metadata in metadataObjects { 

      for barcodeType in barCodeTypes { 

       if metadata.type == barcodeType { 
        barCodeObject = self.previewLayer.transformedMetadataObjectForMetadataObject(metadata as! AVMetadataMachineReadableCodeObject) 

        highlightViewRect = barCodeObject.bounds 

        detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

        self.session.stopRunning() 

        self.alert(detectionString) 
        break 
       } 

      } 
     } 

     print(detectionString) 
     self.highlightView.frame = highlightViewRect 
     self.view.bringSubviewToFront(self.highlightView) 

    } 



    func alert(Code: String){ 
     let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.Alert) 

     // for alert add .Alert instead of .Action Sheet 


     // start copy 

     let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: 


      { 
       (alertAction:UIAlertAction!) in 


       // action when pressed 

       self.session.startRunning() 




     }) 

     actionSheet.addAction(firstAlertAction) 

     // end copy 






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

    } 



} 
+0

這很棒,謝謝! –

3

斯威夫特3.0版本:

import UIKit 
import AVFoundation 


class BarCodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 


let session   : AVCaptureSession = AVCaptureSession() 
var previewLayer : AVCaptureVideoPreviewLayer! 
@IBOutlet weak var highlightView: UIView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Allow the view to resize freely 
    //  self.highlightView.autoresizingMask = UIViewAutoresizing.FlexibleTopMargin | 
    //   UIViewAutoresizing.FlexibleBottomMargin | 
    //   UIViewAutoresizing.FlexibleLeftMargin | 
    //   UIViewAutoresizing.FlexibleRightMargin 
    // 
    // Select the color you want for the completed scan reticle 
    self.highlightView.layer.borderColor = UIColor.green.cgColor 
    self.highlightView.layer.borderWidth = 3 

    // Add it to our controller's view as a subview. 
    self.view.addSubview(self.highlightView) 


    // For the sake of discussion this is the camera 
    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 

    // Create a nilable NSError to hand off to the next method. 
    // Make sure to use the "var" keyword and not "let" 
    var error : NSError? = nil 
    var input: AVCaptureDeviceInput = AVCaptureDeviceInput() 
    do { 
     input = try AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput 
    } catch let myJSONError { 
     print(myJSONError) 
    } 

    // If our input is not nil then add it to the session, otherwise we're kind of done! 
    if input != AVCaptureDeviceInput() { 
     session.addInput(input) 
    } 
    else { 
     // This is fine for a demo, do something real with this in your app. :) 
     print(error!) 
    } 

    let output = AVCaptureMetadataOutput() 
    output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 
    session.addOutput(output) 
    output.metadataObjectTypes = output.availableMetadataObjectTypes 


    previewLayer = AVCaptureVideoPreviewLayer(session: session) 
    previewLayer.frame = self.view.bounds 
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
    self.view.layer.addSublayer(previewLayer) 

    // Start the scanner. You'll have to end it yourself later. 
    session.startRunning() 

} 

// This is called when we find a known barcode type with the camera. 
@nonobjc func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 

    var highlightViewRect = CGRect() 

    var barCodeObject : AVMetadataObject! 

    var detectionString : String! 

    let barCodeTypes = [AVMetadataObjectTypeUPCECode, 
         AVMetadataObjectTypeCode39Code, 
         AVMetadataObjectTypeCode39Mod43Code, 
         AVMetadataObjectTypeEAN13Code, 
         AVMetadataObjectTypeEAN8Code, 
         AVMetadataObjectTypeCode93Code, 
         AVMetadataObjectTypeCode128Code, 
         AVMetadataObjectTypePDF417Code, 
         AVMetadataObjectTypeQRCode, 
         AVMetadataObjectTypeAztecCode 
    ] 


    // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan. 
    for metadata in metadataObjects { 

     for barcodeType in barCodeTypes { 

      if metadata.type == barcodeType { 
       barCodeObject = self.previewLayer.transformedMetadataObject(for: metadata as! AVMetadataMachineReadableCodeObject) 

       highlightViewRect = barCodeObject.bounds 

       detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue 

       self.session.stopRunning() 

       self.alert(Code: detectionString) 
       break 
      } 

     } 
    } 

    print(detectionString) 
    self.highlightView.frame = highlightViewRect 
    self.view.bringSubview(toFront: self.highlightView) 

} 



func alert(Code: String){ 
    let actionSheet:UIAlertController = UIAlertController(title: "Barcode", message: "\(Code)", preferredStyle: UIAlertControllerStyle.alert) 

    // for alert add .Alert instead of .Action Sheet 


    // start copy 

    let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: 


     { 
      (alertAction:UIAlertAction!) in 


      // action when pressed 

      self.session.startRunning() 




    }) 

    actionSheet.addAction(firstAlertAction) 

    // end copy 






    self.present(actionSheet, animated: true, completion: nil) 

} 

}在SWIFT 3.0