1

私は、2番目の画面としてVNDocumentCameraViewControlleraに埋め込まれUIViewControllerRepresentableたビューにa を持っています。(スキャンのキャンセル時または保存時に) を閉じると、タブ ビューが最初の画面に戻ります。その部分は魅力のように機能します。ScanViewTabViewVNDocumentCameraViewController

私の問題は、に戻ったときに、VNDocumentCameraViewControllerそのコントローラーを再インスタンス化して最初からやり直したいということです。これは、それを達成する方法がわかりません。

ContentViewへの参照を保持していることが原因でScanView、が再インスタンス化されないことは承知してUIViewControllerRepresentableいます。どうすれば手動で再インスタンス化できますか?

コードは次のとおりです。

import SwiftUI

@main
struct so_VisionKitInTabsApp: App {
        var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var tabSelection = 1

    var body: some View {
        TabView(selection: $tabSelection) {
            Text("First View")
                .tabItem { Text("First View") }
                .tag(1)
            ScanView(tabSelection: $tabSelection)
                .tabItem { Text("Scan View") }
                .tag(2)
        }
    }
}

import VisionKit

struct DocumentScanningViewAdapter: UIViewControllerRepresentable {
    typealias UIViewControllerType = VNDocumentCameraViewController

    let onDismiss: () -> ()
        
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }

    func makeUIViewController(context: Context) -> VNDocumentCameraViewController {
        let vc = VNDocumentCameraViewController()
        vc.delegate = context.coordinator
        return vc
    }
    
    func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: Context) { }

    class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
        var parent: DocumentScanningViewAdapter
        
        init(parent: DocumentScanningViewAdapter) {
            self.parent = parent
        }
        
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
            print("Finished successfully…")
            parent.onDismiss()
        }
        
        func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
            print("Cancelled…")
            resetCoordinator(for: controller)
            parent.onDismiss()
        }
        
        func resetCoordinator(for controller: VNDocumentCameraViewController) {
            controller.delegate = parent.makeCoordinator()
        }
    }
    
}

struct ScanView: View {
    @Binding var tabSelection: Int
    
    var body: some View {
        DocumentScanningViewAdapter(onDismiss: { tabSelection = 1 })
    }
}
4

2 に答える 2

1

上記の Philip の回答のおかげで、 を使用できることが示唆され、を使用する.sheetこの新しいものを思いつきました。ScanView.fullScreenCover

仕事はしますが、それはタブバーをカバーします(私はそれと一緒に暮らすことができると思います)。

struct ScanView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var showFullscreen = true
    @Binding var tabSelection: Int
    
    var body: some View {
        EmptyView()
            .fullScreenCover(isPresented: $showFullscreen, onDismiss: {
                presentationMode.wrappedValue.dismiss()
            }) {
                DocumentScanningViewAdapter(onDismiss: {
                    showFullscreen = false
                    tabSelection = 1
                })
            }
            .onAppear {
                showFullscreen = true
            }
    }
}
于 2021-08-17T07:33:30.097 に答える