【问题标题】:Swift PDFKit: Inconsistent behaviour with PDFView.currentDestination and PDFView.go(to destination: PDFDestination)Swift PDFKit:与 PDFView.currentDestination 和 PDFView.go 不一致的行为(到目的地:PDFDestination)
【发布时间】:2021-11-17 08:26:30
【问题描述】:

注意:这个问题暂时没有解决;标记的答案提供了一个很好的解决方法 - 它在应用程序仍处于打开状态时工作。 仍然欢迎回答!

背景

我目前正在开发一个包含全屏PDFView 的应用程序,我希望程序在视图被关闭之前记住文档中的位置,以便用户可以从他们离开的地方继续。

实施

应用程序的简化版本可以理解为使用PDFKit.PDFView 的PDF 查看器。故事板由一个连接到 PDFView 类 DocumentView(符合 UIViewController)的 UIView 组成。视图通过以下过程初始化:

viewDidLoad:

let PDF: PDFDocument = GetPDFFromServer()
DocumentView.document = PDF!
DocumentView.autoScales = true
... (other settings)

// Set PDF Destination
let Destination: PDFDestination = GetStoredDestination()
// Code with issues
DocumentView.go(to: Destination)

viewWillDisappear:

StoreDestination(DocumentView.currentDestination)

问题与测试

我意识到代码没有按预期工作;视图不会返回到之前的位置。

通过调试,我意识到这可能是由于DocumentView.go(to destination: PDFDestination)DocumentView.currentDestination的行为不一致造成的。

为确保存储位置时不会因错误而引入错误,以下代码用于验证问题,并带有多页文档:

viewDidLoad

Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in
    DispatchQueue.main.async {
    
self.DocumentView.go(to:self.DocumentView.currentDestination!)
    }

})

预期和观察到的行为

预期:文档的位置不应更改 - 代码将每 1 秒到达其当前目的地,这应该没有影响。因为“currentDestination”应该是“文档的当前目的地,每个文档”)

观察到:在执行时,页面会自发地向下滚动一个固定的偏移量。

在 iPadOS 14.5 模拟器和 iPadOS 15 iPad Air(第 4 代)上观察到相同的结果。

可能出了什么问题?

如果有人能帮忙就太好了。

干杯, 林肯

这个问题最初是在一周前发布在Apple Developer Forum上的;一个多星期没有收到任何回复,所以我想我可以在 StackOverflow 上试试运气

【问题讨论】:

  • 您能否发布 DocumentView 的代码,以及在关闭前一个视图后如何再次创建它?
  • 当然,将编辑问题并解决该问题。
  • 嘿 - 我已经更新了这个问题,提供了有关此问题的更多详细信息。提前致谢!

标签: ios swift ipados ios-pdfkit


【解决方案1】:

我在这种情况下尝试了PDFView.go(),我设法让它在某些情况下工作,但发现它在其他一些情况下会失败,例如缩放文档、改变方向。

所以回到你想要实现的目标,

我目前正在开发一个包含全屏的应用 PDFView,我希望程序记住在 在视图被关闭之前记录文档,以便用户可以在哪里找到 他们已经离开了。

这可以通过不同的方法来完成。使用这种方法,您需要始终保留对您创建的PDFView 的引用。如果需要再次加载之前的 pdf,则将 PDFView 实例传递给 viewController 。否则,您将新的 pdf 加载到 PDFView 实例并将其传递给 viewController

DocumentViewController 在初始化时获得PDFView

import UIKit
import PDFKit

protocol DocumentViewControllerDelegate: AnyObject {
    func needsContinuePDF(continuePDF: Bool)
}

class DocumentViewController: UIViewController {
    var pdfView: PDFView!
    weak var delegate: DocumentViewControllerDelegate!
    
    init(pdfView: PDFView, delegate: DocumentViewControllerDelegate){
        self.pdfView = pdfView
        self.delegate = delegate
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func loadView() {
        super.loadView()
        self.view.backgroundColor = .white
        view.addSubview(pdfView)
        NSLayoutConstraint.activate([
            pdfView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            pdfView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            pdfView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            pdfView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        delegate.needsContinuePDF(continuePDF: true)
    }
}

你可以像下面这样初始化DocumentViewControllerMainViewController负责初始化PDFView

import UIKit
import PDFKit

class MainViewController: UIViewController {
    var pdfView: PDFView = PDFView()
    var continuePreviousPDF = false
    
    let button = UIButton(frame: .zero)
    
    override func loadView() {
        super.loadView()
        
        button.setTitle("View PDF", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .systemBlue
        button.addTarget(self, action: #selector(openDocumentView(_:)), for: .touchUpInside)
        self.view.backgroundColor = .systemGray5
        self.view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.widthAnchor.constraint(equalToConstant: 100),
            button.heightAnchor.constraint(equalToConstant: 50),
            button.centerXAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerYAnchor),
        ])
    }
    
    @objc func openDocumentView(_ sender: UIButton) {
        //open a nee PDF if not continue previous one
        if !self.continuePreviousPDF {
            pdfView.autoScales = true
            pdfView.displayMode = .singlePageContinuous
            pdfView.translatesAutoresizingMaskIntoConstraints = false
            
            guard let path = Bundle.main.url(forResource: "sample copy", withExtension: "pdf") else { return }

            if let document = PDFDocument(url: path) {
                pdfView.document = document
            }
        }
        
        let documentViewController = DocumentViewController(pdfView: pdfView, delegate: self)
        self.present(documentViewController, animated: true, completion: nil)
    }
}

extension MainViewController: DocumentViewControllerDelegate {
    func needsContinuePDF(continuePDF: Bool) {
        self.continuePreviousPDF = continuePDF
    }
}

【讨论】:

  • 嗨 SamB,感谢您的出色贡献!这对我有用。但是,一旦应用程序关闭,pdfView 实例将被销毁,因此在重新启动应用程序后它将无法工作。有没有办法将目的地存储在 UserDefaults (或其他地方)中,以便用户在重新启动应用程序后可以从他们离开的地方拿起?非常感谢。
  • PDFDestination 类无法编码。但是您可以对 pageNumber、目标点进行编码,然后从 UserDefaults 中获取这些并将其重新创建为 PDFDestination(page: , at: )。但是,我尝试在 OP 中以您的方法创建一个新的 PDFDestination,并尝试在第二次加载 pdf 时使用它滚动到正确的位置。那并不完美。所以我不确定它是否适用于这个答案。请注意,如果您采用这种方法,您也必须担心 PDFView.scaleFactor(即放大/缩小)
  • 谢谢,这是我最初的方法,尽管它似乎没有按预期工作。我怀疑在调用 PDFView.go(to destination: ) 时,视图可能会尝试将该目标居中,而 PDFView.currentDestination 从页面的左下角计算目标。如果有任何进展,我会尝试并更新这个答案 - 我正在考虑添加一个视图高度和宽度一半的偏移量。同时,感谢您的帮助。
  • 如果您可以让 PDFView.go(to destination) 工作,请发布答案。我现在也对如何在这种情况下工作感兴趣:)。也看看 PDFView.currentPage,我注意到它有时可能与 PDFView.currentDestination.page 不同。
  • 这似乎不是问题所在。刚刚做了一个测试,发现它使用PDFView.go(to destination:)的实际目的地低于输入目的地(即FinalDestination.point.y d仅取决于屏幕尺寸而不是其他任何东西(哪个文档等),只要设备不变,它就保持一致。我用几个模拟器检索了偏移量d,将它与视图大小和屏幕大小进行了对比,但没有发现任何关系(期待线性关系)。这很奇怪——可能是一个错误?
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 2013-09-02
  • 2020-02-28
  • 2022-01-24
相关资源
最近更新 更多