So I am using PDFKit to display a PDF and and save/open the last read page. Here's my code. Problem is, the last open page is always 2-4 pages ahead of the one that's actually saved in user defaults. I am not sure what's wrong here.
Ignore the the code with the WebView for iOS versions below 11.
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)
}
For me, I'm seeing an "Index from 0" vs. "Index from 1" issue. I believe that under the hood some changes have recently been made to PDFKit.
It's possible this wouldn't have worked in the past...
Using Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53) Target: x86_64-apple-darwin19.5.0
and Xcode Version 11.5 (11E608c)
This works for me:
var currentPageNumber: Int {
let result = pdfView.currentPage?.pageRef?.pageNumber ?? 0
return result > 0 ? result - 1 : 0
}
One Possible way to save the currently viewed page's page number:
/// 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)
}
I call this from 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)
}
}
Again: YMMV , but this works for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.