Buenas tardes Le presento la continuación del artículo "Descargue, guarde y vea PDF en Swift", como prometió el autor: veremos más de cerca el PDFKit.
PDFKit apareció en iOS 11, y tiene 3 excelentes características de las que me gustaría hablar en el proceso de creación de una aplicación de lector de libros electrónicos:
paginación ,
contenido de pantalla e
icono de página.
Todos los que estén interesados, bienvenidos a cat.


Paginación, esquema y miniaturasCrear un PDFViewController con Inyección de inicializadorAl crear la variable
URL en el PDFViewController, lo hicimos inmutable. Es por eso que elegí
Inyección de inicializador en lugar de
Inyección de propiedad o
Inyección de método .
La única variable a implementar es
pdfUrl , y el resto:
documento y
esquema , son accesibles a través del alcance de la clase local y pueden iniciarse mediante
init () .
El contenido de
pdfView no cambia, por lo que lo
designé con el
documento variable y también lo inicialicé a través de
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) } }
Establecer paginación horizontalAhora tenemos el contenido en el documento, que hemos
escrito en
pdfView.document . Para realizar un desplazamiento horizontal, como en un libro, debe agregar varias configuraciones a 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 }
Iconos de página para una fácil navegaciónPDFKit tiene algo increíblemente útil como ThumbnailView. Todo lo que necesita hacer es asignar nuestro
pdfView a la propiedad
thumbnailView.pdfView . ¡Y eso es todo! Sin delegados, notificaciones u otras configuraciones.
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) }
Mostrar contenido para la navegación de capítulosPara llegar a una página específica, necesitamos transferir una página específica (
PDFPage ) a
pdfView . Por lo tanto, debemos profundizar en la jerarquía del contenido (
esquema ) en el documento (
documento ) para llegar a la página (
página ) deseada.

Estoy usando
UITableViewController como una ventana emergente (
popOver ). Por lo tanto, necesito:
- Crea un protocolo. UITableViewController debe seguir este protocolo.
- Agregue algunos métodos de delegado para acceder a pdfView en el PDFViewController .
- Llame al método delegado cuando el usuario selecciona una celda 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) } } }

¡Hurra! Entonces aplicamos las 3 funciones principales de PDFKit. Todavía hay algunos detalles triviales de la interfaz, pero en este artículo no nos centraremos en ellos. El proyecto está disponible para todos.