我正在尝试显示加载,而屏幕上尚未显示PDF。问题是,我的加载总是在文档已经呈现之前停止,有时可能需要2到3秒钟,并且我需要知道何时已经呈现PDF才能停止activyIndicator。使用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()
}
}
}
答案 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
}