0

I have a SwiftUI iOS app that I have made available for mac catalyst. I am using QuickLook Preview to dispaly pdf, docx, images and pptx in the app. The rendering works fine on iOS but on MacOS, only 1 page of the document is displayed with a blurry look.

Here is my code that implements the QuickLook:

import SwiftUI
import QuickLook

struct PreviewController: UIViewControllerRepresentable {

@Binding var 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
    }
    
}
}

and then I calling it in my Content view in a sheet. Question is what do I do differently to render the documents properly on the MacOS?

Heyman
  • 449
  • 4
  • 13
  • Embedding QLPreviewController in a view that then shows up in a sheet is quite tricky. Have you tried using the native .quickLook SwiftUI API instead? – Thomas Deniau Dec 13 '21 at 19:54
  • @ThomasDeniau I had no idea about this modifier. Looks like I could use that. But could you provide me with an example? As I am not very sure how that works. Thanks a lot – Heyman Dec 13 '21 at 20:10
  • I have tried using .quickLookPreview modifier on a ZStack in my ContentView but it throws the error `Value of type 'some View' has no member 'quickLookPreview` on mac however, It works well on iOS so what is the problem here? – Heyman Dec 13 '21 at 21:05
  • I had no idea it didn't work on Catalyst, sorry. File a bug? The problem with Catalyst is that it does not support embedding a QLPreviewController's view (since on Catalyst QLPreviewController is bridged to a macOS preview panel), which is what you are trying to achieve here. Embedded views are replaced with thumbnails IIRC, I guess that's what you're seeing. Not sure what the solution is. I'm not super familiar with SwiftUI / Catalyst. Maybe you can call the macOS quickLook view modifier directly? This one ought to work? – Thomas Deniau Dec 15 '21 at 10:09

1 Answers1

2

I finally found a working solution to this problem.The trick is to display the quicklook preview in a navigationViewController. here is the code:

struct PreviewControllerMac: UIViewControllerRepresentable {
@Binding var url: URL

func makeUIViewController(context: Context) -> UINavigationController {
    let controller = QLPreviewController()
    controller.dataSource = context.coordinator
    controller.delegate = context.coordinator
    let navigationController = UINavigationController(rootViewController: controller)
    return navigationController
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
func makeCoordinator() -> Coordinator {
    return Coordinator(parent: self)
}
class Coordinator: NSObject, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
    let parent: PreviewControllerMac
    init(parent: PreviewControllerMac) {
        self.parent = parent
    }
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return parent.url as NSURL
}
func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
return .updateContents
    }
}
Heyman
  • 449
  • 4
  • 13