在SwiftUI中使用UIViewControllerRepresentable呈现UIDocumentInteractionController [英] Presenting UIDocumentInteractionController with UIViewControllerRepresentable in SwiftUI

查看:386
本文介绍了在SwiftUI中使用UIViewControllerRepresentable呈现UIDocumentInteractionController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尽可能使用SwiftUI创建一个新的iOS应用.但是,我希望能够生成包含一些数据的PDF. 在没有swiftUI的类似项目中,我可以做到

I'm creating a new iOS app using SwiftUI where ever possible. However, I want to be able to generate a PDF with some data. In a similar project without swiftUI I can do this

let docController = UIDocumentInteractionController.init(url: "PATH_TO_FILE")
                        docController.delegate = self
                        self.dismiss(animated: false, completion: {
                            docController.presentPreview(animated: true)
                        })

,只要在视图控制器中的其他地方,我就会这样:

and as long as somewhere else in the view controller I have this:

func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self
    }

我很好. 我无法解决的是如何将其应用于UIViewControllerRepresentable并使它在SwiftUI中工作.我的UIViewControllerRepresentable是否应该成为UIViewController?然后如何设置委托和presentPreview?这会像我的标准iOS应用程序一样在我的SwiftUI应用程序上覆盖任何视图并全屏显示吗? 谢谢

I'm good to go. What I can't work out is how to apply this to a UIViewControllerRepresentable and have it working in SwiftUI. Should my UIViewControllerRepresentable be aiming to be a UIViewController? How do I then set the delegate and presentPreview? Will this overlay any view and display full screen over my SwiftUI app as it does for my standard iOS app? Thanks

推荐答案

以下是将UIDocumentInteractionController集成以在SwiftUI视图中使用的可行方法.

Here is possible approach to integrate UIDocumentInteractionController for usage from SwiftUI view.

全模块代码.经过Xcode 11.2/iOS 13.2的测试

Full-module code. Tested with Xcode 11.2 / iOS 13.2

import SwiftUI
import UIKit

struct DocumentPreview: UIViewControllerRepresentable {
    private var isActive: Binding<Bool>
    private let viewController = UIViewController()
    private let docController: UIDocumentInteractionController

    init(_ isActive: Binding<Bool>, url: URL) {
        self.isActive = isActive
        self.docController = UIDocumentInteractionController(url: url)
    }

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

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<DocumentPreview>) {
        if self.isActive.wrappedValue && docController.delegate == nil { // to not show twice
            docController.delegate = context.coordinator
            self.docController.presentPreview(animated: true)
        }
    }

    func makeCoordinator() -> Coordintor {
        return Coordintor(owner: self)
    }

    final class Coordintor: NSObject, UIDocumentInteractionControllerDelegate { // works as delegate
        let owner: DocumentPreview
        init(owner: DocumentPreview) {
            self.owner = owner
        }
        func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
            return owner.viewController
        }

        func documentInteractionControllerDidEndPreview(_ controller: UIDocumentInteractionController) {
            controller.delegate = nil // done, so unlink self
            owner.isActive.wrappedValue = false // notify external about done
        }
    }
}

// Demo of possible usage
struct DemoPDFPreview: View {
    @State private var showPreview = false // state activating preview

    var body: some View {
        VStack {
            Button("Show Preview") { self.showPreview = true }
                .background(DocumentPreview($showPreview, // no matter where it is, because no content
                            url: Bundle.main.url(forResource: "example", withExtension: "pdf")!))
        }
    }
}

struct DemoPDFPreview_Previews: PreviewProvider {
    static var previews: some View {
        DemoPDFPreview()
    }
}

这篇关于在SwiftUI中使用UIViewControllerRepresentable呈现UIDocumentInteractionController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆