2

当使用 VisionKit 的 VNDocumentCameraViewController 扫描文档时,相机会在几秒钟后挂起。扫描在 SwiftUI 中使用的 ViewController 中实现。

DocumentScannerViewController的实现:

import UIKit
import VisionKit
import SwiftUI

final class DocumentScannerViewController: UIViewController, VNDocumentCameraViewControllerDelegate, UIViewControllerRepresentable {
    public typealias UIViewControllerType = DocumentScannerViewController

    public func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentScannerViewController>) -> DocumentScannerViewController {
        return DocumentScannerViewController()
    }

    public func updateUIViewController(_ uiViewController: DocumentScannerViewController, context: UIViewControllerRepresentableContext<DocumentScannerViewController>) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let scannerViewController = VNDocumentCameraViewController()
        scannerViewController.delegate = self as VNDocumentCameraViewControllerDelegate
        view.addSubview(scannerViewController.view)
    }

    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
    }

    func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
    }

    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
    }
}

以及ContentView的实现:

import SwiftUI

struct ContentView: View {
    var body: some View {
        DocumentScannerViewController()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

文档扫描相机启动并工作一小段时间。然后相机停止移动。

知道是什么导致了这种行为吗?

4

1 回答 1

2

Apple 确实提供了一种ViewControllers在 SwiftUI 视图中使用的方法UIViewControllerRepresentable,您必须使用这种方法来实现。

首先声明您的视图如下:

import SwiftUI
import UIKit
import Vision
import VisionKit

struct ScanningVNDocumentView: UIViewControllerRepresentable  {

    // implement your custom init() in case ..

    typealias UIViewControllerType = VNDocumentCameraViewController

    func makeUIViewController(context: UIViewControllerRepresentableContext<ScanningVNDocumentView>) -> VNDocumentCameraViewController {
        let viewController = VNDocumentCameraViewController()
        viewController.delegate = context.coordinator
        return viewController
    }

    func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: UIViewControllerRepresentableContext<ScanningVNDocumentView>) {

    }

    func makeCoordinator() -> Coordinator {
    //Coordinator is Apple bridge between SwiftUI and ViewController
        return Coordinator() `// this basically call init of the UIViewControllerRepresentable above`

    }

    final class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
        @Environment(\.presentationMode) var presentationMode

        init() {

        }
        // implement VNDocumentCameraViewControllerDelegate methods where you can dismiss the ViewController
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
            print("user did press save with scanned docs numbers \(scan.pageCount) ")
        }

        func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
    print("Did press cancel")
         }


        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
            print("Document camera view controller did finish with error ", error)

        }
    }
}

你现在可以这样调用你的视图:

var body: some View {
    ScanningVNDocumentView()
}
于 2020-01-24T10:23:27.033 回答