如何使相机功能仅显示在一个选项卡栏项中?

时间:2018-12-05 18:26:20

标签: ios swift

我当前正在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)
                }
            }
        }
    }
}

3 个答案:

答案 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")
    }

}