The only solution that worked for me without too much hacking was to add the QLPreviewController
's view as the single subview of another parent view controller.
By that you can add whatever navigation or toolbar you want. Keep in mind that hacking away / updating / adding stuff into existing native UI elements might break whenever iOS is updated.
It would look something like that, I'm using it to preview and share PDF files. The PDF file was downloaded before to fileURL
.
final class PreviewController: UIViewController, QLPreviewControllerDataSource {
/// The `QLPreviewController` hosting the PDF preview.
private var previewController = QLPreviewController(nibName: nil, bundle: nil)
/// The `URL` pointing to the device's filesystem.
let fileURL: URL
// MARK: - Init
/// Creates an instance of `PreviewController` showing the PDF file at the given path.
/// - Parameters:
/// - fileURL: The `URL` of the PDF file.
/// - title: The title to show on the view controller.
init(fileURL: URL, title: String?) {
self.fileURL = fileURL
super.init()
self.title = title
setShareButton()
previewController.dataSource = self
}
required init?(coder: NSCoder) { nil }
// MARK: - Setup
override func viewDidLoad() {
super.viewDidLoad()
addPreview()
}
/// Adds PDF preview to view hierarchy.
private func addPreview() {
addChild(previewController)
view.addSubview(previewController.view)
previewController.didMove(toParent: self)
// +Setup constraints or set previewController.view.frame = view.frame here
}
/// Sets share button.
private func setShareButton() {
let shareButton = UIBarButtonItem(
// It looks a little bit different to the original icon, apply scaling if needed.
image: UIImage(systemName: "square.and.arrow.up"),
primaryAction: .init(handler: { _ in
self.tappedShareButton()
}))
navigationItem.leftBarButtonItem = shareButton
}
/// Share button handler method.
private func tappedShareButton() {
let shareSheet = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
present(shareSheet, animated: true)
shareSheet.popoverPresentationController?.barButtonItem = navigationItem.leftBarButtonItem
}
// MARK: - QLPreviewControllerDataSource
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
fileURL as QLPreviewItem
}
}