我当前正在Xcode 10中创建QR扫描仪/阅读器应用程序。我有一个Tab控制器,其中有两个选项卡栏项。
1。)主页
2。)QR扫描仪
尽管,我的代码可以工作,并且我可以在“第二个视图控制器”中扫描QR码,但是每当我切换到“第一个视图控制器”时,如果我不想要它,它仍会扫描QR码。如果您有关于如何解决此问题的任何提示,将不胜感激。
第一视图控制器:
import UIKit
class FirstViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
}
}
第二视图控制器:
import UIKit
import AVFoundation
class SecondViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var video = AVCaptureVideoPreviewLayer()
@IBOutlet weak var square: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
//Creating session
let session = AVCaptureSession()
//Define Capture device
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do {
let input = try AVCaptureDeviceInput(device: captureDevice!)
session.addInput(input)
} catch {
print (">>>>Error")
}
let output = AVCaptureMetadataOutput ()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubviewToFront(square)
session.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects != nil && metadataObjects.count != 0 {
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject{
if object.type == AVMetadataObject.ObjectType.qr{
let alert = UIAlertController(title: "QR code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
present(alert,animated: true, completion: nil)
}
}
}
}
}
答案 0 :(得分:2)
我建议将会话添加为类中的成员变量,而不是仅添加viewDidLoad()方法。
现在,您可以在viewWillAppear()方法中调用session.startRunning(),而在viewWillDisappear中,您可以调用session.stopRunning()
这是基本布局:
class SecondViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let session = AVCaptureSession()
override func viewDidLoad() {
// any setup you may need
}
override func viewWillAppear() {
// ensure everything is setup correctly
session.startRunning()
}
override func viewWillDisappear() {
// anything before navigating away
session.stopRunning()
}
}
答案 1 :(得分:0)
您已经开始了AVCaptureSession
会话,但是没有明确停止它。每当在控制器之间切换时,系统可能会将控制器保留在内存中。
您将要执行session.stopRunning()
,然后离开控制器并进行清理。例如。在viewWillDisappear
或类似的版本中。
参考:https://developer.apple.com/documentation/avfoundation/avcapturesession/1385661-stoprunning
答案 2 :(得分:0)
感谢大家的帮助。查看代码后,我意识到我要做的是重写viewDidAppear()和viewDidDisappear()。
工作代码:
class SecondViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let session = AVCaptureSession()
override func viewDidLoad() {
// any setup you may need
}
override func viewWillAppear(_ animated: Bool) {
session.startRunning()
print("Start running")
}
override func viewDidDisappear(_ animated: Bool) {
session.stopRunning()
print ("Stop running")
}
}