问题描述
这是我在程序中使用的条形码扫描教程,因此,当您阅读我的代码时,您会拥有更多的上下文:Link
这是我的程序到目前为止执行的操作:本质上,当我用手机扫描物品的条形码时,UIAlert会弹出并显示显示的条形码ID和一个按钮,提示用户打开“结果”页面。一切都很好,但是如何将相同的扫描条形码ID传递到结果页面上的标签?我已经坚持了两天,即使这看起来很容易。
非常感谢任何帮助
这是我的相关代码:
ProductCatalog.plist -> Link to Image
Scanner_ViewController.swift (第一个View控制器)->
import UIKit
import AVFoundation
class Scanner_ViewController: UIViewController,AVCaptureMetadataOutputObjectsDelegate,ScannerDelegate
{
private var scanner: Scanner?
override func viewDidLoad()
{
super.viewDidLoad()
self.scanner = Scanner(withDelegate: self)
guard let scanner = self.scanner else
{
return
}
scanner.requestCaptureSessionStartRunning()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// dispose of any resources that can be recreated.
}
// Mark - AVFoundation delegate methods
public func MetadataOutput(_ output: AVCaptureMetadataOutput,didOutput MetadataObjects: [AVMetadataObject],from connection: AVCaptureConnection)
{
guard let scanner = self.scanner else
{
return
}
scanner.MetadataOutput(output,didOutput: MetadataObjects,from: connection)
}
// Mark - Scanner delegate methods
func cameraview() -> UIView
{
return self.view
}
func delegateViewController() -> UIViewController
{
return self
}
func scanCompleted(withCode code: String)
{
print(code)
showAlert_Success(withTitle: (code))
}
private func showAlert_Success(withTitle title: String)
{
let alertController = UIAlertController(title: title,message: "Product has been successfully scanned",preferredStyle: .alert)
// programatically segue to the next view controller when the UIAlert pops up
alertController.addAction(UIAlertAction(title:"Get Results",style: .default,handler:{ action in self.performSegue(withIdentifier: "toAnalysisPage",sender: self) }))
present(alertController,animated: true)
}
}
Scanner.Swift (随附Scanner_ViewController.swift)->
import Foundation
import UIKit
import AVFoundation
protocol ScannerDelegate: class
{
func cameraview() -> UIView
func delegateViewController() -> UIViewController
func scanCompleted(withCode code: String)
}
class Scanner: NSObject
{
public weak var delegate: ScannerDelegate?
private var captureSession : AVCaptureSession?
init(withDelegate delegate: ScannerDelegate)
{
self.delegate = delegate
super.init()
self.scannerSetup()
}
private func scannerSetup()
{
guard let captureSession = self.createCaptureSession()
else
{
return
}
self.captureSession = captureSession
guard let delegate = self.delegate
else
{
return
}
let cameraview = delegate.cameraview()
let previewLayer = self.createPreviewLayer(withCaptureSession: captureSession,view: cameraview)
cameraview.layer.addSublayer(previewLayer)
}
private func createCaptureSession() -> AVCaptureSession?
{
do
{
let captureSession = AVCaptureSession()
guard let captureDevice = AVCaptureDevice.default(for: .video) else
{
return nil
}
let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
let MetaDataOutput = AVCaptureMetadataOutput()
// add device input
if captureSession.canAddInput(deviceInput) && captureSession.canAddOutput(MetaDataOutput)
{
captureSession.addInput(deviceInput)
captureSession.addOutput(MetaDataOutput)
guard let delegate = self.delegate,let viewController = delegate.delegateViewController() as? AVCaptureMetadataOutputObjectsDelegate else
{
return nil
}
MetaDataOutput.setMetadataObjectsDelegate(viewController,queue: dispatchQueue.main)
MetaDataOutput.MetadataObjectTypes = self.MetaObjectTypes()
return captureSession
}
}
catch
{
// handle error
}
return nil
}
private func createPreviewLayer(withCaptureSession captureSession: AVCaptureSession,view: UIView) -> AVCaptureVideoPreviewLayer
{
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
return previewLayer
}
private func MetaObjectTypes() -> [AVMetadataObject.ObjectType]
{
return [.qr,.code128,.code39,.code39Mod43,.code93,.ean13,.ean8,.interleaved2of5,.itf14,.pdf417,.upce
]
}
public func MetadataOutput(_ output: AVCaptureMetadataOutput,from connection: AVCaptureConnection)
{
self.requestCaptureSessionStopRunning()
guard let MetadataObject = MetadataObjects.first,let readableObject = MetadataObject as? AVMetadataMachineReadableCodeObject,let scannedValue = readableObject.stringValue,let delegate = self.delegate
else
{
return
}
delegate.scanCompleted(withCode: scannedValue)
}
public func requestCaptureSessionStartRunning()
{
self.toggleCaptureSessionRunningState()
}
public func requestCaptureSessionStopRunning()
{
self.toggleCaptureSessionRunningState()
}
private func toggleCaptureSessionRunningState()
{
guard let captureSession = self.captureSession
else
{
return
}
if !captureSession.isRunning
{
captureSession.startRunning()
}
else
{
captureSession.stopRunning()
}
}
}
Analysis_ViewController.swift (第二个视图控制器)->
现在,forKey:已被硬编码为商品ID 8710908501708,因为我不知道如何将相机扫描的ID实际传递到第二个View Controller中:/
import UIKit
class Analysis_ViewController: UIViewController
{
@IBOutlet weak var productTitle: UILabel!
func getData()
{
let path = Bundle.main.path(forResource:"ProductCatalog",ofType: "plist")
let dict:NSDictionary = NSDictionary(contentsOfFile: path!)!
if (dict.object(forKey: "8710908501708" as Any) != nil)
{
if let levelDict:[String : Any] = dict.object(forKey: "8710908501708" as Any) as? [String : Any]
{
// use a for loop to iterate through all the keys and values in side the "Levels" dictionary
for (key,value) in levelDict
{
// if we find a key named whatever we care about,we can print out the value
if (key == "name")
{
productTitle.text = (value as! String)
}
}
}
}
}
// listing the better options that are safer in comparison to the scanned product image
override func viewDidLoad()
{
super.viewDidLoad()
getData()
}
}
解决方法
您是否有一个变量将视图ID保留在视图控制器中?如果没有,则可以将var itemID: String?
添加到Scanner_ViewController
和Analysis_ViewController
中。
然后在函数中获取扫描代码的地方,可以将其设置为变量。
func scanCompleted(withCode code: String) {
print(code)
itemID = code // Saves the scanned code to your var
showAlert_Success(withTitle: (code))
}
要通过segue将数据传递到另一个视图控制器,您可能需要研究以下针对segue的UIViewController方法:documentation here。这个answer也可能有帮助。
override func prepare(for segue: UIStoryboardSegue,sender: Any?) {
if segue.identifier == "toAnalysisPage" {
if let viewController = segue.destination as? Analysis_ViewController {
viewController.itemID = itemID
}
}
}