0

I´m trying to display a Quick Look View directly - without a sheet Presenting the Reality File. If I start the App at the first time it works fine:

Quick Look View at first Start

when I'm switching between a TabView back to the first ModelView I don't the the reality Model anymore:

Quick Look View after switching Tab

I tried

.onAppear {
  PreviewController(url: self.fileUrl)
                }

but this doesn't work. I also tried SceneKit, it worked here but here I can only use usdz-Files. If I'm Presenting the sheet with the Button it's working fine.

Here the Files:

ModelView.swift

import SwiftUI

struct ModelView: View {
    
    let fileUrl = Bundle.main.url(forResource: "LunarRover_English", withExtension: "reality")!
    @State private var showingPreview = false
    
    var body: some View {
        ScrollView{
            Text("Rover")
                .font(.title2)
                .onAppear {
                    print("ARVRView-Text")
                    //self.showingPreview = true
                    //PreviewController(url: self.fileUrl)
                }
            
            ZStack(alignment: .topTrailing){
                PreviewController(url: self.fileUrl)
                    .aspectRatio(1.20, contentMode: .fit)
                Button {
                    self.showingPreview = true
                } label: { 
                    Image(systemName: "rectangle.expand.vertical")
                }
                .sheet(isPresented: $showingPreview) {
                    VStack(spacing: 0) {
                        HStack {
                            Button("Zurück") {
                                self.showingPreview = false
                            }
                            Spacer()
                        }
                        .padding()
                        
                        PreviewController(url: self.fileUrl)
                    }
                }
                .foregroundColor(.black)
                .imageScale(.large)
                .symbolRenderingMode(.hierarchical)
                .offset(x:-10, y:10)
            }
        }
    }
}

struct ARVRView_Previews: PreviewProvider {
    static var previews: some View {
        ARVRView()
    }
}

PreviewController.swift

import SwiftUI
import UIKit
import QuickLook

struct PreviewController: UIViewControllerRepresentable {
    
    let url: URL
    
    func makeUIViewController(context: Context) -> QLPreviewController {
        let controller = QLPreviewController()
        controller.dataSource = context.coordinator
        return controller
    }
    
    func updateUIViewController(
        _ uiViewController: QLPreviewController, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }
    
    class Coordinator: QLPreviewControllerDataSource {
        
        let parent: PreviewController
        
        init(parent: PreviewController) {
            self.parent = parent
        }
        
        func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
            return 1
        }
        
        func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
            return parent.url as NSURL
        }
        
    }
}
Andx
  • 51
  • 4
  • You need to call reloadData – Leo Dabus Jan 23 '22 at 18:19
  • Try calling `uiViewController.reloadData()` inside `updateUIViewController` – Leo Dabus Jan 23 '22 at 18:20
  • @LeoDabus thanks for your Help, but I it doesn't work: `func updateUIViewController( _ uiViewController: QLPreviewController, context: Context) { uiViewController.reloadData() }` – Andx Jan 23 '22 at 18:47
  • Is your method getting called? – Leo Dabus Jan 23 '22 at 19:12
  • try `func updateUIViewController(_ viewController: UINavigationController, context: UIViewControllerRepresentableContext) { (viewController.topViewController as? QLPreviewController)?.reloadData() }` – Leo Dabus Jan 23 '22 at 19:13
  • How do I call the method? Sorry I just started developing with SwiftUI: If I use your code I will get an Error: `Type PreviewController does not conform to protocol 'UIViewControllerRepresentable` – Andx Jan 23 '22 at 21:13
  • try `func makeUIViewController(context: Context) -> UINavigationController {` – Leo Dabus Jan 23 '22 at 21:15
  • again is `updateUIViewController` being called ? You don't have to explicitly call that method – Leo Dabus Jan 23 '22 at 21:16
  • @LeoDabus thanks again!I think I have called both `makeUIViewController` and `updateUIViewController` in the `struct PreviewController: UIViewControllerRepresentable {` the `PreviewController.swift` file. Take a look at the code or do I understand it wrong? – Andx Jan 23 '22 at 22:25
  • This [post](https://stackoverflow.com/a/67639527/2303865) might help – Leo Dabus Jan 23 '22 at 22:34
  • @LeoDabus no that doesnt work - I found a solution if I [toggle the PreviewController](https://stackoverflow.com/a/70836305/17825074) – Andx Jan 24 '22 at 15:30

1 Answers1

1

The post from Leo Dabus doesnt work, I´ve tried it with a pdf / usdz-File. It looks like you have to toggle the PreviewController(url: self.fileUrl) with a .toggle() / Button / Sheet or something else. But I think that isn´t to best solution?

Solution

Add the follwing @State for Toggle onAppear:

@State private var showingPreview2 = false
Text("Rover")
  .onAppear {
       print("Toggle")
       showingPreview2.toggle()
            }
if showingPreview2 {
                    Text("if true")
                    PreviewController(url: self.fileUrl)
                        .aspectRatio(1.20, contentMode: .fit)
} else {
                    Text("else")
                    PreviewController(url: self.fileUrl)
                        .aspectRatio(1.20, contentMode: .fit)
                }
Andx
  • 51
  • 4