QRCode Scanner triggert mehrfach

  • QRCode Scanner triggert mehrfach

    Neu

    Quellcode

    1. import UIKit
    2. import AVFoundation
    3. class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    4. var scannedID: Int32 = -1
    5. var cfgItmdict = NSDictionary()
    6. var captureSession:AVCaptureSession?
    7. var videoPreviewLayer:AVCaptureVideoPreviewLayer?
    8. var qrCodeFrameView:UIView?
    9. let supportedCodeTypes = [AVMetadataObjectTypeUPCECode,
    10. AVMetadataObjectTypeCode39Code,
    11. AVMetadataObjectTypeCode39Mod43Code,
    12. AVMetadataObjectTypeCode93Code,
    13. AVMetadataObjectTypeCode128Code,
    14. AVMetadataObjectTypeEAN8Code,
    15. AVMetadataObjectTypeEAN13Code,
    16. AVMetadataObjectTypeAztecCode,
    17. AVMetadataObjectTypePDF417Code,
    18. AVMetadataObjectTypeQRCode]
    19. @IBOutlet weak var topbar: UIView!
    20. @IBOutlet weak var messageLable: UILabel!
    21. override func viewDidLoad() {
    22. super.viewDidLoad()
    23. qrcodescan()
    24. // Do any additional setup after loading the view.
    25. }
    26. override func didReceiveMemoryWarning() {
    27. super.didReceiveMemoryWarning()
    28. // Dispose of any resources that can be recreated.
    29. }
    30. @IBAction func exitScan(_ sender: Any) {
    31. dismiss(animated: true, completion: nil)
    32. }
    33. func qrcodescan() {
    34. let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
    35. do {
    36. // Get an instance of the AVCaptureDeviceInput class using the previous device object.
    37. let input = try AVCaptureDeviceInput(device: captureDevice)
    38. // Initialize the captureSession object.
    39. captureSession = AVCaptureSession()
    40. // Set the input device on the capture session.
    41. captureSession?.addInput(input)
    42. // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
    43. let captureMetadataOutput = AVCaptureMetadataOutput()
    44. captureSession?.addOutput(captureMetadataOutput)
    45. // Set delegate and use the default dispatch queue to execute the call back
    46. captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    47. captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
    48. // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
    49. videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    50. videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    51. videoPreviewLayer?.frame = view.layer.bounds
    52. view.layer.addSublayer(videoPreviewLayer!)
    53. // Start video capture.
    54. captureSession?.startRunning()
    55. // Move the message label and top bar to the front
    56. view.bringSubview(toFront: messageLable)
    57. view.bringSubview(toFront: topbar)
    58. // Initialize QR Code Frame to highlight the QR code
    59. qrCodeFrameView = UIView()
    60. if let qrCodeFrameView = qrCodeFrameView {
    61. qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
    62. qrCodeFrameView.layer.borderWidth = 2
    63. view.addSubview(qrCodeFrameView)
    64. view.bringSubview(toFront: qrCodeFrameView)
    65. }
    66. } catch {
    67. // If any error occurs, simply print it out and don't continue any more.
    68. print(error)
    69. return
    70. }
    71. }
    72. func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
    73. // Check if the metadataObjects array is not nil and it contains at least one object.
    74. if metadataObjects == nil || metadataObjects.count == 0 {
    75. qrCodeFrameView?.frame = CGRect.zero
    76. messageLable.text = "No QR/barcode is detected"
    77. return
    78. }
    79. // Get the metadata object.
    80. let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    81. if supportedCodeTypes.contains(metadataObj.type) {
    82. // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
    83. let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
    84. qrCodeFrameView?.frame = barCodeObject!.bounds
    85. if metadataObj.stringValue != nil {
    86. messageLable.text = metadataObj.stringValue
    87. scannedID = Int32(metadataObj.stringValue)!
    88. performSegue(withIdentifier: "segueBackHome", sender: self)
    89. }
    90. }
    91. }
    92. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    93. if segue.identifier == "segueBackHome" {
    94. let homeViewController = segue.destination as! HomeViewController
    95. homeViewController.scanID = scannedID
    96. }
    97. }
    98. /*
    99. // MARK: - Navigation
    100. // In a storyboard-based application, you will often want to do a little preparation before navigation
    101. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    102. // Get the new view controller using segue.destinationViewController.
    103. // Pass the selected object to the new view controller.
    104. }
    105. */
    106. }
    Alles anzeigen
    Hallo,

    ich habe in meine App einen QRCode Scanner eingebaut, nach einem Tutorial das ich im Internet gefunden habe. Der Scanner an sich funktioniert super. Nach erkennen eines Codes soll ein Segue ausführt werden, mit dem dann der gescannte Wert zurück übergeben wird. Es ist allerdings so, das dieses Segue 2mal ausgeführt wird so das ich in einem Navigationcontroller-Foo lande.

    Es geht um diese Stelle:
    if metadataObj.stringValue != nil {
    messageLable.text = metadataObj.stringValue
    scannedID = Int32(metadataObj.stringValue)!

    performSegue(withIdentifier: "segueBackHome", sender: self)

    Wie kann ich verhindern, das dieses segue 2 mal ausgeführt wird?.

    Danke

    Dirk
  • Neu

    anstelle von != nil solltest du mit if let arbeiten (wie dir auch schon im anderen Thread geraten wurde)
    dann kannst du auch die Konstante benutzen und musst nicht immer metadataObj.stringValue benutzen
    und du muss auch für den cast zu deiner scannedID kein "!" benutzen

    vielleicht doch mal einen blick ein einführende Swift Literatur werfen

    zu deinem eigentlich Problem, du solltest nicht verhindern das dein performSeque doppel ausgeführt wird sondern wirkt es eher so als würde dein kompletter code doppelt ausgeführt werden und dir mal anschauen warum das passiert
    Ich weiß nicht immer wovon ich rede aber ich weiß das ich Recht habe. :saint: