Show action buttons in export previews
QLPreviewController only renders its share, print and open-in actions when it is inside a navigation controller, so diagram and report previews were dead ends. Wrap it in one, add an explicit Done button and assert both in a UI test.
This commit is contained in:
@@ -232,8 +232,10 @@ struct LoadsView: View {
|
||||
)
|
||||
) {
|
||||
if let previewURL {
|
||||
QuickLookPreview(url: previewURL)
|
||||
.ignoresSafeArea()
|
||||
QuickLookPreview(url: previewURL) {
|
||||
self.previewURL = nil
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
}
|
||||
.onChange(of: previewURL) { _, newValue in
|
||||
|
||||
@@ -5,38 +5,53 @@
|
||||
|
||||
import QuickLook
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
/// Presents a single exported file (PDF or PNG) in Quick Look so the user can
|
||||
/// inspect it before sharing.
|
||||
///
|
||||
/// SwiftUI's `quickLookPreview(_:)` modifier is macOS-only, so iOS wraps
|
||||
/// `QLPreviewController` directly.
|
||||
/// `QLPreviewController` directly. The controller only shows its action
|
||||
/// buttons — share, print, open in another app — when it sits inside a
|
||||
/// navigation controller, so it is wrapped in one and gets an explicit Done
|
||||
/// button to close the sheet.
|
||||
struct QuickLookPreview: UIViewControllerRepresentable {
|
||||
let url: URL
|
||||
var onDone: () -> Void
|
||||
|
||||
func makeUIViewController(context: Context) -> QLPreviewController {
|
||||
let controller = QLPreviewController()
|
||||
controller.dataSource = context.coordinator
|
||||
return controller
|
||||
func makeUIViewController(context: Context) -> UINavigationController {
|
||||
let preview = QLPreviewController()
|
||||
preview.dataSource = context.coordinator
|
||||
preview.navigationItem.leftBarButtonItem = UIBarButtonItem(
|
||||
barButtonSystemItem: .done,
|
||||
target: context.coordinator,
|
||||
action: #selector(Coordinator.done)
|
||||
)
|
||||
preview.navigationItem.leftBarButtonItem?.accessibilityIdentifier = "quick-look-done-button"
|
||||
return UINavigationController(rootViewController: preview)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ controller: QLPreviewController, context: Context) {
|
||||
func updateUIViewController(_ controller: UINavigationController, context: Context) {
|
||||
context.coordinator.onDone = onDone
|
||||
|
||||
guard context.coordinator.url != url as NSURL else { return }
|
||||
context.coordinator.url = url as NSURL
|
||||
controller.reloadData()
|
||||
(controller.viewControllers.first as? QLPreviewController)?.reloadData()
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(url: url as NSURL)
|
||||
Coordinator(url: url as NSURL, onDone: onDone)
|
||||
}
|
||||
|
||||
// MARK: - Coordinator
|
||||
|
||||
final class Coordinator: NSObject, QLPreviewControllerDataSource {
|
||||
var url: NSURL
|
||||
var onDone: () -> Void
|
||||
|
||||
init(url: NSURL) {
|
||||
init(url: NSURL, onDone: @escaping () -> Void) {
|
||||
self.url = url
|
||||
self.onDone = onDone
|
||||
}
|
||||
|
||||
func numberOfPreviewItems(in controller: QLPreviewController) -> Int { 1 }
|
||||
@@ -44,5 +59,9 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
||||
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
||||
url
|
||||
}
|
||||
|
||||
@objc func done() {
|
||||
onDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user