How do you show a UIViewControllerRepresentable in SwiftUI as a non-sheet?

354 Views Asked by At

There are many tutorials out there on how to show a UIViewControllerRepresentable (e.g. to show a VNDocumentCameraViewController) as a sheet, but is there any way to show it as a regular view using NavigationLink, or just including it in another view.

Currently, if I include it like this:

NavigationLink("Add with camera", destination: ScannerView(completion: {result in  resultHandler(text: result)}))

The view shows up like this (embedded in the tab navigation view instead of taking up the whole screen) and the Save button (completion) does not work: NavigationLink UI result

If I include it straight in the view, Xcode gives me an "Initializer is never used" error and it does not show up in the view.

1

There are 1 best solutions below

2
On BEST ANSWER

To push onto a nav stack, it should be as simple as hiding the navigation bar on the DocumentCamera view. I'm using the implementation here, and with a View as follows:

struct ContentView: View {
    
    @State private var path: [String] = []
        
    var body: some View {
        NavigationStack(path: $path) {
            Form {
                NavigationLink("Show Camera", value: "Camera")
            }
            .navigationDestination(for: String.self) { _ in
                DocumentCamera {
                    path = []
                } resultAction: { _ in
                    
                }
                .ignoresSafeArea()
                .navigationBarHidden(true)
            }
        }
    }
}

which gives a result like this:

enter image description here enter image description here

To include the DocumentCamera in another view:


struct ContentView: View {
    
    @State private var showingCamera = false
        
    var body: some View {
        VStack {
            
            if showingCamera {
                DocumentCamera {
                    showingCamera = false
                } resultAction: { _ in
                    
                }
                .padding()
                .aspectRatio(0.6, contentMode: .fit)
            } else {
                Button("Show camera") {
                    showingCamera = true
                }
            }
        }
    }
}

which gives…

enter image description here enter image description here