2017-05-26 124 views
0

我目前正試圖將一個變量從一個類移動到另一個類。我正在使用AVFramework來讀取QR碼。 QR碼最終讀取到一個字符串變量,然後字符串變量讀取到一個label.text。我想在另一個類的textview中使用完全相同的文本。試圖將變量從一個類移動到另一個類

QRScannerController包含QR碼,而HistoryView是我想重新使用該變量的位置。問題是,一旦我掃描QR碼並移動到歷史視圖,它什麼也不讀。這是我到目前爲止。下面是QRScannerController

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){ 
    if segue.destination .isKind(of:HistoryView.self){ 
     let vc2 = segue.destination as! HistoryView 
     vc2.previousViewController = self 
    } 
} 

@IBOutlet var messageLabel:UILabel! 
@IBOutlet var topbar: UIView! 
@IBOutlet var segmentedControl: UISegmentedControl! 
//@IBOutlet var textFacts: UITextView! 


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



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

@IBAction func unwindToHomeScreen(segue: UIStoryboardSegue) { 
    dismiss(animated: true, completion: nil) 
} 

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 

public 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 { 
      //captureSession?.stopRunning() 

      messageLabel.text = metadataObj.stringValue 
      messageLabel.text = messageLabel.text 

      //let vc: UINavigationController = storyboard?.instantiateViewController(withIdentifier: "View") as! UINavigationController 


      let vc3: UIViewController = storyboard!.instantiateViewController(withIdentifier: "View") //as! UIViewController 

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

     } 
    } 
} 
func transferViewControllerVariables() -> (UILabel){ 
    return messageLabel 
} 
} 

這是歷史觀:

import UIKit 
import AVFoundation 

class HistoryView: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    @IBOutlet var textHistory:UITextView! 
    var previousViewController: QRScannerController? 


    @IBAction func unwindToHomeScreen(segue: UIStoryboardSegue) { 
     dismiss(animated: true, completion: nil) 
    } 

    @IBAction func toMaps(segue: UIStoryboardSegue) { 
     let vc3: UIViewController = storyboard!.instantiateViewController(withIdentifier: "front") //as! UIViewController 

     self.present(vc3, animated: true, completion: nil) 
    } 


    override func viewDidLoad() { 
      super.viewDidLoad() 
      // Do any additional setup after loading the view. 


     let messageLabel = previousViewController?.transferViewControllerVariables() 
     //print(messageLabel.text as Any) 
     textHistory.text = messageLabel?.text 

     } 

     // Do any additional setup after loading the view. 


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


} 
+0

爲什麼你不使用segue,而是在'QRScannerController'中使用'present'和'vc3'?只需將其更改爲「performSegue」,那麼它可以工作 – Tj3n

+0

也許這將有助於https://stackoverflow.com/questions/5210535/passing-data-between-view-controllers – Spads

回答

0

我會建議你只是將實際的文本傳遞給下一個視圖控制器而不是整個以前的視圖控制器。 一般的問題是prepareForSegue函數永遠不會被調用,因爲HistoryView控制器不是通過segue呈現的,而是以編程方式呈現的。

將數據傳遞到記錄閱讀控制器編程做到這一點在QRScannerViewController的captureOutput功能:

let vc3: HistoryView = storyboard!.instantiateViewController(withIdentifier: "View") as! HistoryView 
vc3.messagetext = metadataObj.stringValue 
self.present(vc3, animated: true, completion: nil) 

要在歷史VC添加新的屬性:

class HistoryView: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 
    var messageText: String? 
} 

然後你就可以刪除prepareForSegue函數完全是因爲它不被調用。

+0

我試過了,文字出現空白 – CALVIN

+0

你是否將textHistoryText指定給messageText,如下所示:textHistory.text = messageText?當您到達prepareForReuse時,messageLabel上的文本是否設置? – bughana

+0

是的,我已經分配了文本。我有最後的準備功能。在切換到新視圖之後,應該由此設置消息標籤。 – CALVIN

0

你應該在聲明一個HistoryViewmessageLabel。執行segue時,分配值,就是這樣。

class HistoryView: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 
    var messageLabel: String? 

} 



class QRCodeScanner: UIViewController { 
    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){ 
     if segue.destination.isKind(of:HistoryView.self){ 
      if let vc2 = segue.destination as? HistoryView { 
       vc2.messageLabel = self.messageLabel.text 
      } 
     } 
    } 
} 
+0

首先,QRCodeScanner中的第二條if語句無效,導致了一個錯誤。第二,我得到的錯誤「類型QRScannerController的值沒有成員messageLabel」 – CALVIN

+0

它應該是你的'@IBOutlet var messageLabel:UILabel!' – WeiJay

+0

是的!我已經完成了這個,並且讓它執行,但是文本是空白的。 – CALVIN

相關問題