🦋

SwiftUI: UIKitの万能プレビューを使う

2023/11/20に公開

QLPreviewControllerを使う

struct QuickLookViewRepresentable: UIViewControllerRepresentable {
    let url: URL

    func makeUIViewController(context: Context) -> QLPreviewController {
        let controller = QLPreviewController()
        controller.dataSource = context.coordinator
        return controller
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    func updateUIViewController(_ uiViewController: QLPreviewController, context: Context) {}

    class Coordinator: QLPreviewControllerDataSource {
        let parent: QuickLookViewRepresentable

        init(parent: QuickLookViewRepresentable) {
            self.parent = parent
        }

        func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
            return 1
        }

        func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
            return parent.url as QLPreviewItem
        }
    }
}

UIDocumentInteractionControllerを使う

struct DocumentInteractionView: UIViewControllerRepresentable {
    let url: URL?
    private let viewController = UIViewController()
    private let docController: UIDocumentInteractionController

    init(url: URL?) {
        self.url = url
        self.docController = UIDocumentInteractionController()
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentInteractionView>) -> UIViewController {
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<DocumentInteractionView>) {
        if self.url != nil && docController.delegate == nil {
            docController.url = url
            docController.delegate = context.coordinator
            let result = self.docController.presentPreview(animated: true)
            Swift.print(result)
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    final class Coordinator: NSObject, UIDocumentInteractionControllerDelegate {
        let parent: DocumentInteractionView

        init(parent: DocumentInteractionView) {
            self.parent = parent
        }

        func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
            return parent.viewController
        }

        func documentInteractionControllerDidEndPreview(_ controller: UIDocumentInteractionController) {
            controller.delegate = nil
        }
    }
}

Discussion