Ha habido muchas preguntas recientemente sobre dibujar PDF's.
Sí, puedes renderizar PDF muy fácilmente con un UIWebView
pero esto no puede proporcionar el rendimiento y la funcionalidad que esperaría de un buen visor de PDF.
Puede dibujar una página PDF en un CALayer o en un UIImage . Apple incluso tiene un código de muestra para mostrar cómo dibujar un PDF grande en una vista de desplazamiento UIS con zoom
Pero los mismos problemas siguen apareciendo.
Método UIImage:
- PDF en un
UIImage
escala no óptica, así como un enfoque de capa. - La CPU y la memoria golpean al generar el
UIImages
desdePDFcontext
límites / evitan su uso para crear una representación en tiempo real de nuevos niveles de zoom.
Método CATiledLayer:
- Hay una sobrecarga significativa (tiempo) dibujando una página PDF completa a
CALayer
: se pueden ver mosaicos individuales renderizados (incluso con un ajuste de mosaico) CALayers
no se puede preparar con anticipación (renderizado fuera de pantalla).
En general, los lectores de PDF también tienen bastante memoria. Incluso supervise el uso de memoria del ejemplo de PDF con zoom de Apple.
En mi proyecto actual, estoy desarrollando un visor de PDF y renderizo una UIImage
página en un hilo separado (¡problemas aquí también!) Y la presento mientras la escala es x1. CATiledLayer
la representación comienza una vez que la escala es> 1. iBooks adopta un enfoque similar de doble toma como si desplazara las páginas, puede ver una versión de resolución más baja de la página por menos de un segundo antes de que aparezca una versión nítida.
Estoy renderizando 2 páginas a cada lado de la página en foco para que la imagen PDF esté lista para enmascarar la capa antes de que comience a dibujar. Las páginas se destruyen nuevamente cuando están a +2 páginas de la página enfocada.
¿Alguien tiene alguna idea, no importa cuán pequeña u obvia sea para mejorar el rendimiento / manejo de la memoria de Drawing PDF? o cualquier otro problema discutido aquí?
EDITAR: Algunos consejos (Crédito- Luke Mcneice, VdesmedT, Matt Gallagher, Johann):
Guarde cualquier medio en el disco cuando pueda.
Use tileSizes más grandes si renderiza en TiledLayers
init utiliza matrices frecuentemente con objetos de marcador de posición, alternativamente otro enfoque de diseño es este
Tenga en cuenta que las imágenes se procesarán más rápido que un
CGPDFPageRef
Use
NSOperations
o GCD & Blocks para preparar las páginas con anticipación.llame
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
antesCGContextDrawPDFPage
para reducir el uso de memoria mientras dibujainiciar tu
NSOperations
con un docRef es una mala idea (memoria), envolver el docRef en un singleton.Cancelar innecesariamente
NSOperations
Cuando pueda, especialmente si usarán memoria, ¡tenga cuidado de dejar los contextos abiertos!Reciclar objetos de página y destruir vistas no utilizadas
Cierre los contextos abiertos tan pronto como no los necesite.
al recibir advertencias de memoria, libere y vuelva a cargar el DocRef y cualquier caché de página
Otras características de PDF:
Obtener enlaces dentro de un PDF (y aquí y aquí )
Obtener el objetivo del enlace (Obtener el número de página de la
/Dest
matriz)
Obtener texto sin procesar (y aquí y aquí y aquí (posicionamiento centrado))
Búsqueda (y aquí ) (no funciona con todos los PDF (algunos solo muestran caracteres extraños, supongo que es un problema de codificación, pero no estoy seguro) -Credit BrainFeeder)
CALayer y renderizado fuera de pantalla : renderice la página siguiente para una visualización rápida / fluida
Documentación
- Objetos PDF de cuarzo (Utilizado para metainformación, anotaciones, pulgares)
- Abobe PDF Spec
Proyectos de ejemplo
- Manzana / ZoomingPDF - zoom,
UIScrollView
,CATiledLayer
- VFR / lector - zoom, paginación,
UIScrollView
,CATiledView
- cejas / hojas - paginación con agradables transiciones
- / skim : todo lo que parece (lector / editor de PDF para OSX)
PSPDFKit
, no es barata, pero vale la pena: pspdfkit.comRespuestas:
He creado este tipo de aplicación utilizando aproximadamente el mismo enfoque, excepto:
UIImage
sino que dibujo la imagen en la capa cuando el zoom es 1. Esos mosaicos se liberarán automáticamente cuando se emitan advertencias de memoria.Cada vez que el usuario comienza a hacer zoom, lo adquiero
CGPDFPage
y lo renderizo usando la CTM apropiada. El código en- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context
es como:problema es el objeto que contacta con el
CGPDFDocumentRef
. Sincronizo la parte dondepdfDoc
accedo a la propiedad porque la libero y la vuelvo a crear cuando recibo MemoryWarnings. Parece que elCGPDFDocumentRef
objeto realiza un almacenamiento en caché interno del que no encontré cómo deshacerme.fuente
Para un visor de PDF simple y efectivo, cuando solo necesita una funcionalidad limitada, ahora puede (iOS 4.0+) usar el marco QuickLook:
Primero, debes vincular contra
QuickLook.framework
y#import <QuickLook/QuickLook.h>;
Luego, en
viewDidLoad
cualquiera de los métodos de inicialización diferida:fuente
Desde iOS 11 , puede usar el marco nativo llamado PDFKit para mostrar y manipular archivos PDF.
Después de importar PDFKit, debe inicializar a
PDFView
con una URL local o remota y mostrarlo en su vista.Lea más sobre PDFKit en la documentación para desarrolladores de Apple.
fuente
fuente