2017-05-26 2 views
0

Ich versuche derzeit, eine Variable von einer Klasse in eine andere zu verschieben. Ich benutze die AVFramework, um QR Codes zu lesen. Der QR-Code liest schließlich in eine String-Variable und dann liest die String-Variable in einen label.text. Ich möchte diesen exakt gleichen Text in der Textansicht einer anderen Klasse verwenden.Versuch, eine Variable von einer Klasse in eine andere zu verschieben

QRScannerController enthält den QR-Code, während HistoryView ist, wo ich die Variable wiederverwenden möchte. Das Problem ist, dass wenn ich den QR-Code scanne und in die History-Ansicht gehe, liest es nichts. Hier ist was ich bisher habe. Unten ist die 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 
} 
} 

Dies ist die Geschichte Ansicht:

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

Warum verwenden Sie nicht "segue", sondern '' 'mit' vc3' in 'QRScannerController'? Ändern Sie es einfach in 'performSegue', dann funktioniert es – Tj3n

+0

Vielleicht hilft das https://stackoverflow.com/questions/5210535/passing-data-between-view-controllers – Spads

Antwort

0

Ich würde vorschlagen, dass Sie nur den eigentlichen Text an die nächste Ansicht Controller anstelle der gesamten vorherigen Ansicht Controller übergeben. Das allgemeine Problem ist jedoch, dass die prepareForSegue-Funktion nie aufgerufen wird, da der HistoryView-Controller nicht über ein Segment, sondern programmgesteuert dargestellt wird.

Um Daten an den HistoryView Controller programmatisch tun dies in der captureOutput Funktion im QRScannerViewController passieren:

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

Um eine neue Eigenschaft in der Geschichte vc hinzufügen:

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

Dann können Sie entfernen Die prepareForSegue-Funktion ist vollständig, da sie sowieso nicht aufgerufen wird.

+0

Ich habe es versucht und der Text erscheint leer – CALVIN

+0

Weisen Sie den textHistoryText dem messageText wie folgt zu: textHistory.text = messageText? Und wird der Text im messageLabel gesetzt, wenn Sie prepareForReuse erreichen? – bughana

+0

Ja, ich habe die Texte zugewiesen. Ich habe die Vorbereitungsfunktion zuletzt. Es ist nach dem Wechsel in die neue Ansicht, so dass die Nachrichtenbezeichnung sollte dann eingestellt werden. – CALVIN

0

Sie eine messageLabel in HistoryView erklären. Bei der Durchführung von segue, den Wert zuweisen, und das ist es.

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

Erstens ist Ihre zweite if-Anweisung in der QRCodeScanner ungültig und hat einen Fehler verursacht. Zweitens bekomme ich den Fehler "Wert des Typs QRScannerController hat kein Mitglied messageLabel" – CALVIN

+0

Es sollte Ihre '@IBOutlet var messageLabel: UILabel!' – WeiJay

+0

Ja! Ich habe das getan und habe es ausgeführt, aber der Text erscheint leer. – CALVIN

Verwandte Themen