如何知道何时使用PDFKit渲染PDF

时间:2019-04-10 00:29:08

标签: swift pdfkit

我正在尝试显示加载,而屏幕上尚未显示PDF。问题是,我的加载总是在文档已经呈现之前停止,有时可能需要2到3秒钟,并且我需要知道何时已经呈现PDF才能停止activyIndi​​cator。使用PDFKIT是否可以?我的代码:

class PDFViewController: URLSessionDownloadDelegate {

    @IBOutlet weak var pdfView: PDFView!
    var pdfDocument: PDFDocument!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupPDFView()
        setupNavigationBar()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.startLoading()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        loadPDF()
    }

    private func loadPDF() {
        DispatchQueue.main.async {
            guard let url = URL(string: self.viewModel.pdfURL) else {
                self.showAlert(with: self.viewModel.strings.invalidInvoice)
                return
            }

            let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())

            let downloadTask = urlSession.downloadTask(with: url)
            downloadTask.resume()
        }
    }

    private func setupPDFView() {
        self.pdfView.displayMode = .singlePageContinuous
        self.pdfView.autoScales = true
    }

    func startLoading() {

        guard let window = UIApplication.shared.keyWindow,
            !window.subviews.contains(where: { $0 is LoadingView }) else { return }

        let loadingView = LoadingView(frame: window.bounds)
        window.addSubview(loadingView)

        Thread.performUIUpdate {
            loadingView.startAnimation()
        }
    }

    func stopLoading() {

        guard let window = UIApplication.shared.keyWindow,
        let view = window.subviews.first(where: { $0 is LoadingView }),
        let loadingView = view as? LoadingView  else { return }

        Thread.performUIUpdate {
            loadingView.stopAnimation()
            loadingView.removeFromSuperview()
        }
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        DispatchQueue.main.async {
            self.pdfDocument = PDFDocument(url: location)

            if let pdfDocument = self.pdfDocument {
                self.pdfView.document = pdfDocument
            }

            self?.stopLoading()
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这似乎是一个非常糟糕的主意:

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    DispatchQueue.main.async {
        self.pdfDocument = PDFDocument(url: location)

问题在于,当您离开当前线程并启动异步代码时,该方法将完成,并且location处的临时文档可能会被破坏。我建议这样写:

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    let pdf = PDFDocument(url: location)
    DispatchQueue.main.async {
        self.pdfDocument = pdf

我并不是说这可以解决您的问题,但是危险似乎要比您正在做的事情要轻得多。

关于您的实际问题,我建议注册诸如this one之类的通知,并查看通知是否在适当的时候到达。

答案 1 :(得分:1)

您必须观察PDFViewVisiblePagesChanged通知才能知道何时可见PDFView页面,然后在方法中添加代码。

NotificationCenter.default.addObserver(self, selector: #selector(pdfViewVisiblePagesChanged(sender:)), name: .PDFViewVisiblePagesChanged, object: nil)

@objc func pdfViewVisiblePagesChanged(sender: Notification) {

    //Add your code here
}