Cree un lector de libros electrónicos usando PDFKit en Swift

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.

imagen

imagen

imagen
Paginación, esquema y miniaturas

Crear un PDFViewController con Inyección de inicializador

Al 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 horizontal

Ahora 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 } 

imagen

Iconos de página para una fácil navegación

PDFKit 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) } 

imagen

Mostrar contenido para la navegación de capítulos

Para 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.

imagen

Estoy usando UITableViewController como una ventana emergente ( popOver ). Por lo tanto, necesito:

  1. Crea un protocolo. UITableViewController debe seguir este protocolo.
  2. Agregue algunos métodos de delegado para acceder a pdfView en el PDFViewController .
  3. 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) } } } 

imagen

¡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.

Source: https://habr.com/ru/post/es431012/


All Articles