如何在swift中popup视图控制器后传递数据

我正在制作关于书籍的应用程序。 在应用程序中,我想让应用程序自动填充书籍信息通过获得ISBN(条码)

意见

有两个class。 一个是“UploadMain”,另一个是“ScanView”

我可以通过扫描获得ISBN,但是我有一个问题,要将数据从ScanView传递到UploadMain。

在ScanView中,我使用了如下所示的可选Binding

if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { UploadVC.ISBNstring = self.detectionString! } 

UploadMain类的代码

 override func viewDidLoad(){ super.viewDidLoad() ISBN.delegate = self } override func viewWillAppear(animated: Bool){ ISBN.text = ISBNstring } 

我不知道我的代码是什么问题。

完整的上传代码

 import UIKit import Foundation class UploadMain: UIViewController,UITextFieldDelegate { var ISBNstring: String = "" var TitleString: String = "" var AuthorString: String = "" var PubString: String = "" var PriceSting: String = "" @IBOutlet weak var ISBN: UITextField! @IBOutlet weak var bookTitle: UITextField! @IBOutlet weak var bookAuthor: UITextField! @IBOutlet weak var bookPub: UITextField! @IBOutlet weak var bookPrice: UITextField! override func viewDidLoad(){ super.viewDidLoad() ISBN.delegate = self } override func viewWillAppear(animated: Bool){ ISBN.text = ISBNstring } @IBAction func Upload(sender: AnyObject) { dismissViewControllerAnimated(true, completion: nil) } } 

ScanView类

 import UIKit import AVFoundation import Foundation class ScanView : UIViewController, AVCaptureMetadataOutputObjectsDelegate { let session : AVCaptureSession = AVCaptureSession() var previewLayer : AVCaptureVideoPreviewLayer! var detectionString : String! let apiKey : String = "---------dddddd" override func viewDidLoad() { super.viewDidLoad() // 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! let barCodeTypes = [AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code] // 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) // Daum Book API 호출 let apiURI = NSURL(string: "https://apis.daum.net/search/book?apikey=\(apiKey)&q=\(detectionString)&searchType=isbn&output=json") let apidata : NSData? = NSData(contentsOfURL: apiURI!) NSLog("API Result = %@", NSString(data: apidata!, encoding: NSUTF8StringEncoding)!) **if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { UploadVC.ISBNstring = self.detectionString! }** break } } } print(detectionString) self.navigationController?.popViewControllerAnimated(true) } 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) } } 

ScanView您正在创buildUploadMain的新实例,该实例在窗口层次结构中不可用,所以数据不可用于UploadMain 。 要解决您的问题,您需要创build一个protocol ,并将该protocol的委托传递给ScanView 。 所以创build一个这样的protocol

 protocol IsbnDelegate { func passData(isbnStr: String) } 

现在在UploadMaininheritance这个协议并像下面一样覆盖UploadMain的方法passData

 class UploadMain: UIViewController,UITextFieldDelegate,IsbnDelegate { //your code //Add this method func passData(isbnStr: String) { self.ISBN.text = isbnStr } //Also override prepareForSegue like this override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { let destVC = segue.destinationViewController as! ScanView destVC.delegate = self } } 

之后,在ScanView中创build一个delegate对象,像这样更改ScanView的代码

 import UIKit import AVFoundation import Foundation class ScanView : UIViewController, AVCaptureMetadataOutputObjectsDelegate { let session : AVCaptureSession = AVCaptureSession() var previewLayer : AVCaptureVideoPreviewLayer! var detectionString : String! let apiKey : String = "---------dddddd" var delegate: IsbnDelegate? override func viewDidLoad() { super.viewDidLoad() // 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! let barCodeTypes = [AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code] // 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) // Daum Book API 호출 let apiURI = NSURL(string: "https://apis.daum.net/search/book?apikey=\(apiKey)&q=\(detectionString)&searchType=isbn&output=json") let apidata : NSData? = NSData(contentsOfURL: apiURI!) NSLog("API Result = %@", NSString(data: apidata!, encoding: NSUTF8StringEncoding)!) //Here We are passing the data of your ScanView to UploadMain self.delegate.passData(self.detectionString!) break } } } print(detectionString) self.navigationController?.popViewControllerAnimated(true) } 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) } } 

有关protcol更多详细信息,请点击此链接

1) 苹果文档
2) 教程1
3) 教程2

希望这会帮助你。

对我来说,看来你是从视图控制器传数据。

当你调用if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { UploadVC.ISBNstring = self.detectionString! } if let UploadVC = self.storyboard?.instantiateViewControllerWithIdentifier("UploadMain") as? UploadMain { UploadVC.ISBNstring = self.detectionString! }

您正在创build该视图控制器的新实例,并且它正在成功接收数据(但您永远不能使用它)。

你想要做的是发送数据

我可以为你写出来,但实际上是一些很棒的教程

文本
video