Boa tarde Apresento a você a continuação do artigo "Baixe, salve e visualize PDF no Swift", como o autor prometeu - veremos mais de perto o PDFKit.
O PDFKit apareceu no iOS 11 e possui três ótimos recursos sobre os quais gostaria de falar no processo de criação de um aplicativo leitor de e-book: paginação, exibição de
conteúdo e
ícone da página.
Todo mundo que estiver interessado, bem-vindo ao gato.


Paginação, estrutura de tópicos e miniaturasCriando um PDFViewController com injeção de inicializadorAo criar a variável de
URL no PDFViewController, tornamos imutável. Por isso, escolhi a
injeção de inicializador em vez de
injeção de propriedade ou
injeção de método .
A única variável a implementar é o
pdfUrl , e o restante:
document e
outline , são acessíveis através do escopo da classe local e podem ser iniciados via
init () .
O conteúdo do
pdfView não muda, então eu o
designei com o
documento variável e também o inicializei via
init () .
import UIKit import PDFKit class PDFViewController: UIViewController { private let pdfUrl: URL private let document: PDFDocument! private let outline: PDFOutline? private var pdfView = PDFView() init(pdfUrl: URL) { self.pdfUrl = pdfUrl self.document = PDFDocument(url: pdfUrl) self.outline = document.outlineRoot pdfView.document = document super.init(nibName: nil, bundle: nil) } ... override func viewDidLoad() { super.viewDidLoad() view.addSubview(pdfView) } }
import UIKit class ViewController: UIViewController { @IBAction func openPdfPressed(_ sender: Any) { guard let path = Bundle.main.url(forResource: "swift", withExtension: "pdf") else { print("failed to unwrap fileURL") return } let pdfViewController = PDFViewController(pdfUrl: path) present(pdfViewController, animated: true, completion: nil) } }
Definir paginação horizontalAgora temos o conteúdo do documento, que
escrevemos em
pdfView.document . Para fazer uma rolagem horizontal, como em um livro, você precisa adicionar várias configurações ao PDFView.
private func setupPDFView() { view.addSubview(pdfView) pdfView.displayDirection = .horizontal pdfView.usePageViewController(true) pdfView.pageBreakMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) pdfView.autoScales = true }
Ícones da página para facilitar a navegaçãoO PDFKit tem uma coisa incrivelmente útil, como o ThumbnailView. Tudo o que você precisa fazer é atribuir nosso
pdfView à propriedade
thumbnailView.pdfView . E isso é tudo! Não há delegados, notificações ou outras configurações.
private func setupThumbnailView() { thumbnailView.pdfView = pdfView thumbnailView.backgroundColor = UIColor(displayP3Red: 179/255, green: 179/255, blue: 179/255, alpha: 0.5) thumbnailView.layoutMode = .horizontal thumbnailView.thumbnailSize = CGSize(width: 80, height: 100) thumbnailView.contentInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) view.addSubview(thumbnailView) }
Exibir conteúdo para a navegação de capítulosPara chegar a uma página específica, precisamos transferir uma página específica (
PDFPage ) para o
pdfView . Portanto, precisamos nos aprofundar na hierarquia do conteúdo (
estrutura de tópicos ) no documento (
documento ) para chegar à página desejada (
página ).

Eu estou usando
UITableViewController como um pop-up (
popOver ). Portanto, eu preciso de:
- Crie um protocolo. UITableViewController deve seguir este protocolo.
- Adicione alguns métodos de delegação para acessar o pdfView no PDFViewController .
- Chame o método delegado quando o usuário selecionar uma célula específica.
import UIKit import PDFKit protocol OutlineDelegate: class { func goTo(page: PDFPage) } class OutlineTableViewController: UITableViewController { let outline: PDFOutline weak var delegate: OutlineDelegate? init(outline: PDFOutline, delegate: OutlineDelegate?) { self.outline = outline self.delegate = delegate super.init(nibName: nil, bundle: nil) } ... override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return outline.numberOfChildren } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell if let label = cell.textLabel, let title = outline.child(at: indexPath.row)?.label { label.text = String(title) } return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let page = outline.child(at: indexPath.row)?.destination?.page { delegate?.goTo(page: page) } } }

Viva! Então, aplicamos as 3 principais funções do PDFKit. Ainda existem alguns detalhes triviais da interface, mas neste artigo não iremos focar neles. O projeto está disponível para todos.