swiftswiftuiuiviewcontrollerrepresentable

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


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.


Solution

  • 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