0

所以我使用 PDFKit 来显示 PDF 并保存/打开最后阅读的页面。这是我的代码。问题是,最后打开的页面总是比实际保存在用户默认值中的页面早 2-4 页。我不确定这里有什么问题。

忽略 11 以下 iOS 版本的 WebView 的代码。

func readBook() {

    if let oldBookView = self.view.viewWithTag(3) {
        oldBookView.removeFromSuperview()
        // This removes the old book view when the user chooses a new book language
    }

    if #available(iOS 11.0, *) {
        let pdfView: PDFView = PDFView()
        let path = BookManager.getBookPath(bookLanguageCode: book.bookLanguageCode)
        let url = URL(fileURLWithPath: path)
        if let pdfDocument = PDFDocument(url: url) {
            pdfView.displayMode = .singlePageContinuous
            pdfView.autoScales = true
            pdfView.document = pdfDocument
            pdfView.tag = 3 // I assigned a tag to this view so that later on I can easily find and remove it when the user chooses a new book language
            let lastReadPage = getLastReadPage()

            if let page = pdfDocument.page(at: lastReadPage) {
                pdfView.go(to: page)
                // Subscribe to notifications so the last read page can be saved
                // Must subscribe after displaying the last read page or else, the first page will be displayed instead
                NotificationCenter.default.addObserver(self, selector: #selector(self.saveLastReadPage),name: .PDFViewPageChanged, object: nil)
            }
        }

        self.containerView.addSubview(pdfView)
        setConstraints(view: pdfView)
        addTapGesture(view: pdfView)
    } else {
        let path = BookManager.getBookPath(bookLanguageCode: book.bookLanguageCode)
        let url = URL(fileURLWithPath: path)
        let webView: WKWebView = WKWebView()
        webView.loadFileURL(url, allowingReadAccessTo: url)
        webView.tag = 3 // I assigned a tag to this view so that later on I can easily find and remove it when the user chooses a new book language

        self.containerView.addSubview(webView)
        setConstraints(view: webView)
        addTapGesture(view: webView)
    }
}

private func getLastReadPage() -> Int {
    let readPagesDictionary: [String:Int] = DataManager.UserDefaultsManager.value(for: .lastReadPage)
    let bookLanguage = book.bookLanguageCode
    let lastReadPage = readPagesDictionary[bookLanguage]

    return lastReadPage!
}

@available(iOS 11.0, *)
@objc private func saveLastReadPage(notification: Notification) {
    let pdfView = notification.object as! PDFView
    var page = pdfView.currentDestination?.page?.pageRef?.pageNumber
    let bookLanguage = book.bookLanguageCode
    var readPageDict: [String:Int] = DataManager.UserDefaultsManager.value(for: .lastReadPage)
    readPageDict.updateValue(page!, forKey: bookLanguage)
    DataManager.UserDefaultsManager.set(readPageDict, for: .lastReadPage)
}
4

1 回答 1

0

对我来说,我看到了“从 0 开始的索引”与“从 1 开始的索引”的问题。我相信最近对 PDFKit 进行了一些更改。

这在过去可能不会奏效......

使用 Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53) Target: x86_64-apple-darwin19.5.0Xcode Version 11.5 (11E608c)

这对我有用:

   var currentPageNumber: Int  {
        let result = pdfView.currentPage?.pageRef?.pageNumber ?? 0
        return result > 0 ? result - 1 : 0
    }

保存当前查看页面的页码的一种可能方法:

    /// integer(forKey:) returns 0 when not found, which is perfect place to scroll to
    /// this only addresses the case you are viewing the same document that was saved to user defaults
    /// if you've gone to a new file, start at 0 there
    /// you could update the document proxy to contain a last page saved if you have one, 
    /// and when opening the pdf, save that to user defaults
    func saveCurrentPageNumber() {
        UserDefaults.standard.set(currentPageNumber, forKey: pageNumberKey)
    }

我称之为viewWillAppear()

/// Check user defaults and scroll to last page viewed (or 0 if none)
func scrollToSavedPage() {
    let pageNumber = UserDefaults.standard.integer(forKey: pageNumberKey)
    if let goToPage = document?.page(at: pageNumber) {
        pdfView.go(to: goToPage)
    }
}

再次:YMMV,但这对我有用。

于 2020-06-11T16:45:14.090 回答