我正在使用 AppCoda 的 QR 码阅读器代码 (http://www.appcoda.com/qr-code-reader-swift/#comments) 并将其转换为 Swift 3。基本代码工作得很好。
但是,我想要实现的是从 QR 阅读器检索字符串,将其存储在变量中,并将变量传递给以下视图控制器。所以我向其中添加了一些代码以获得以下结果:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
messageLabel.text = "No barcode/QR code is detected"
return
}
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if supportedBarCodes.contains(metadataObj.type) {
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
if metadataObj.stringValue != nil {
messageLabel.text = metadataObj.stringValue
}
//
//
// CODE I ADDED STARTS BELOW
//
performSegue(withIdentifier: "showMenu", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMenu"{
let tabVc = segue.destination as! UITabBarController
let navVc = tabVc.viewControllers?.first as! UINavigationController
let menuVc = navVc.viewControllers.first as! MenuViewController
menuVc.qrScan = self.messageLabel.text
}
它实际上实现了我想要它做的事情,但它不知何故多次触发“performSegue”。第一个segue的过渡动画进行到一半,然后发生第二个。
segue“showMenu”是一个手动segue,从 QR 阅读器视图的视图控制器连接到包含导航控制器和菜单视图控制器的选项卡栏控制器。
我尝试过的事情:
在菜单视图控制器的viewdidload函数中打印传递的变量。该字符串被打印两次。
在QR阅读器视图上添加了一个隐藏按钮,并将“showMenu”的segue连接从视图控制器更改为该按钮。从代码中删除了执行segue。将相机固定到位扫描二维码时,按下按钮即可执行预期功能,并且转场仅触发一次。
使用与(2)相同的设置,当扫描二维码时,我通过使用内部触摸事件以编程方式触发按钮。 Segue 被触发两次。
为performSegue 及其上方的if 子句添加了断点。当我扫描一些东西后,按下“继续程序执行”按钮,程序就在两个断点之间循环。
如果有人能在这里启发我一点,我将非常感激。非常感谢您提前提供的帮助。
通过在执行 segue 后添加以下代码行解决了该问题:
self.captureSession?.stopRunning()
但是,为什么 unwind segue 没有类似的问题仍然存在。
我刚刚解决了同样的问题。您必须创建到上一个视图的展开。
要在界面生成器中执行此操作,您必须按住 Ctrl 键并从控制器拖动到您实际所在的控制器(而不是您想要展开的控制器)的出口。
完成此操作后,您必须为此展开转场设置一个标识符(在您的情况下为“showMenu”)。为此,您必须从左侧的场景菜单中展开转场,并在属性检查器。
Swift 5 只需停止扫描仪并根据委托的要求关闭屏幕即可修复
//Assign delegate
if (captureSession?.canAddOutput(metadataOutput) ?? false) {
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr, .ean8, .ean13, .pdf417, .code128]
} else {
return
}
//Use delegate output
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
dismiss(animated: true)
}