2017-07-25 190 views
-1

觸發segue到另一個視圖控制器截至目前,我的qr代碼掃描器只能夠掃描到web url,我怎樣才能觸發從我的qrscannercontroller到另一個segue推送的UIViewController? 我的朋友已經完成了使用QR碼靜態文本的android studio。從qr代碼掃描器(Xcode/Swift)

這是我qrscannercontroller.swift

import UIKit 
import AVFoundation 

class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    @IBOutlet var messageLabel:UILabel! 
    @IBOutlet var topbar: UIView! 

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

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

    override func viewDidLoad() { 
     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.defaultDevice(withMediaType: AVMediaTypeVideo) 

     do { 
      // Get an instance of the AVCaptureDeviceInput class using the previous device object. 
      let input = try AVCaptureDeviceInput(device: captureDevice) 

      // Initialize the captureSession object. 
      captureSession = AVCaptureSession() 

      // Set the input device on the capture session. 
      captureSession?.addInput(input) 

      // 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: DispatchQueue.main) 
      captureMetadataOutput.metadataObjectTypes = supportedCodeTypes 

      // 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 and top bar to the front 
      view.bringSubview(toFront: messageLabel) 
      view.bringSubview(toFront: topbar) 

      // Initialize QR Code Frame to highlight the QR code 
      qrCodeFrameView = UIView() 

      if let qrCodeFrameView = qrCodeFrameView { 
       qrCodeFrameView.layer.borderColor = UIColor.green.cgColor 
       qrCodeFrameView.layer.borderWidth = 2 
       view.addSubview(qrCodeFrameView) 
       view.bringSubview(toFront: qrCodeFrameView) 
      } 

     } catch { 
      // If any error occurs, simply print it out and don't continue any more. 
      print(error) 
      return 
     } 
    } 

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


    // MARK: - AVCaptureMetadataOutputObjectsDelegate Methods 

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from 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 = CGRect.zero 
      messageLabel.text = "No QR/barcode is detected" 
      return 
     } 

     // Get the metadata object. 
     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 

      if metadataObj.stringValue != nil { 
       let url = URL(string: metadataObj.stringValue)! 
       if #available(iOS 10.0, *) { 
        UIApplication.shared.open(url, options: [:], completionHandler: nil) 
       } else { 
        UIApplication.shared.openURL(url) 
       } 
      } 
     } 
    } 

} 

這是我的UIViewController

import UIKit  
class Quiz1Controller: UIViewController {  
    override func viewDidLoad() { 
     super.viewDidLoad()  
     // Do any additional setup after loading the view. 
    } 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 
+0

更改代碼與URL打開segue代碼 –

+0

是否有任何示例/解決方案,你可以告訴我嗎?我對Xcode很抱歉。 – Kinja

回答

0
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 

     //Here you can implement the code to push viewController 

     } 
    } 

您可以使用performSegue(withIdentifier: yourId, sender: nil)從故事板連接SEGUE後,也可以使用

self.navigationController?.pushViewController(yourNextViewController, animated: true) 
0

你必須檢查,天氣url可以打開。如果您掃描url,它將在瀏覽器中打開。如果它不是url那麼你可以根據你的邏輯處理這個動作。

請勿強制拆開URL值。它返回optional value。因此,使用if let以確保價值不nil

if let url = URL(string: metadataObj.stringValue) { 
     if UIApplication.shared.canOpenURL(url) { 
      if #available(iOS 10.0, *) { 
       UIApplication.shared.open(url, options: [:], completionHandler: nil) 
      } else { 
       UIApplication.shared.openURL(url) 
      } 
     } else { 
      //Logic to choose view controller identifier 
      performSegue(withIdentifier: "quiz1VC segue id", sender: self) 
     } 
} 

更新:

問題: 「QR碼掃描完成塊執行多次」

解決方案:

if let _ = metadataObj.stringValue { 
    captureSession?.stopRunning() // Stop session before perform segue. 
    self.performSegueWithIdentifier("abc", sender: self) 
} 
+0

嗨@Subramanian,實際上我不想再使用網址了,我只希望我的qr代碼掃描器鏈接到10 uiviewcontroller,而不是基於生成的10個qr代碼 – Kinja

+0

您是在掃描url還是一些文本? – Subramanian

+0

@Kinja如果您正在掃描一些文本,請使用您的視圖控制器segue id與掃描文本相同。並添加只執行'執行Segue(withIdentifier:「掃描身份證,發件人:自己)'。如果你爲多個掃描文本匹配一個視圖控制器,然後使用'switch case'選擇'segue id' – Subramanian