sale lanzamiento fecha descargar cuando compatibilidad ios pdf calayer

lanzamiento - ios 12 iphone 7



Visor de PDF rápido y ligero para iPhone/iPad/iOs: ¿consejos y sugerencias? (4)

Desde iOS 11 , puede usar el marco nativo llamado PDFKit para visualizar y manipular archivos PDF.

Después de importar PDFKit, debe inicializar un PDFView con una URL local o remota y mostrarlo en su vista.

if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") { let pdfView = PDFView(frame: view.frame) pdfView.document = PDFDocument(url: url) view.addSubview(pdfView) }

Lea más sobre PDFKit en la documentación para desarrolladores de Apple.

Ha habido muchas preguntas recientemente sobre el dibujo de PDF.

Sí, puede renderizar PDF''s 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 para un CALayer o un UIImage . Apple incluso tiene código de ejemplo para mostrar cómo dibujar un PDF grande en una vista de UIScroll con Zoomable

Pero los mismos problemas siguen apareciendo.

Método UIImage:

  1. Los PDF en un UIImage no se escalan ópticamente, así como un enfoque de Capa.
  2. La CPU y la memoria UIImages la generación de UIImages partir de un PDFcontext limita / evita su uso para crear una representación en tiempo real de nuevos niveles de zoom.

Método CATiledLayer:

  1. Existe una sobrecarga significativa (tiempo) al dibujar una página PDF completa para un CALayer : se pueden ver mosaicos individuales (incluso con un ajuste de CALayer azulejo)
  2. CALayers no pueden prepararse con anticipación (renderizados fuera de pantalla).

En general, los visores de PDF también son bastante pesados ​​en la memoria Incluso controlar el uso de memoria del ejemplo de PDF con zoom de Apple.

En mi proyecto actual, estoy desarrollando un visor de PDF y estoy renderizando un UIImage de una página en un hilo separado (¡problemas también aquí!) Y lo presento mientras la escala es x1. CATiledLayer representación de CATiledLayer una vez que la escala es> 1. iBooks adopta un enfoque similar de doble toma, ya que si se desplaza por las páginas, puede ver una versión con menor resolución de la página por solo menos de un segundo antes de que aparezca una versión nítida.

Estoy renderizando 2 páginas de cada lado de la página enfocada para que la imagen PDF esté lista para enmascarar la capa antes de comenzar a dibujar. Las páginas se destruyen de nuevo cuando están a una distancia de +2 de la página enfocada.

¿Alguien tiene alguna información, no importa cuán pequeña u obvia sea para mejorar el rendimiento / manejo de memoria de los PDF de Drawing? ¿O cualquier otro tema discutido aquí?

EDITAR: Algunos consejos (crédito- Luke Mcneice, VdesmedT, Matt Gallagher, Johann):

  • Guarda cualquier medio en el disco cuando puedas.

  • Utilice tamaños de azulejos más grandes si se renderiza en TiledLayers

  • A menudo se utilizan matrices con objetos de marcadores de posición, alternativamente, este es otro enfoque de diseño.

  • Tenga en cuenta que las imágenes se renderizarán más rápido que un CGPDFPageRef

  • Use NSOperations o GCD & Blocks para preparar páginas con anticipación.

  • llame a CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault); CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault); antes de CGContextDrawPDFPage para reducir el uso de memoria mientras se dibuja

  • iniciar sus NSOperations con un docRef es una mala idea (memoria), envuelva el docRef en un singleton.

  • Cancele las innecesarias NSOperations Cuando pueda, especialmente si van a usar la memoria, ¡tenga cuidado de dejar los contextos abiertos!

  • Recicla objetos de la página y destruye vistas no utilizadas

  • Cierre cualquier contexto abierto tan pronto como no los necesite

  • Al recibir advertencias de memoria, libere y vuelva a cargar DocRef y cualquier página.

Otras características de PDF:

Documentación

Proyectos de ejemplo


He desarrollado este tipo de aplicación utilizando aproximadamente el mismo enfoque, excepto:

  • Almaceno en caché la imagen generada en el disco y siempre genero de dos a tres imágenes por adelantado en un hilo separado.
  • No superpongo con un 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 inicia el zoom, CGPDFPage el CGPDFPage y lo represento utilizando el CTM apropiado. El código en - (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context es como:

CGAffineTransform currentCTM = CGContextGetCTM(context); if (currentCTM.a == 1.0 && baseImage) { //Calculate ideal scale CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width; CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height; CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight); CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor); CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height); CGContextDrawImage(context, imageRect, [baseImage CGImage]); } else { @synchronized(issue) { CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1); pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true); CGContextConcatCTM(context, pdfToPageTransform); CGContextDrawPDFPage(context, pdfPage); } }

problema es el objeto que contiene el CGPDFDocumentRef . Sincronizo la parte donde pdfDoc propiedad pdfDoc porque la libero y la vuelvo a crear cuando recibo MemoryWarnings. Parece que el objeto CGPDFDocumentRef un almacenamiento interno en caché del que no encontré cómo deshacerme de él.


Para un visor de PDF simple y efectivo, cuando solo necesita una funcionalidad limitada, ahora puede (iOS 4.0+) usar el marco QuickLook:

Primero, debe vincular con QuickLook.framework y #import <QuickLook/QuickLook.h>;

Luego, en viewDidLoad o en cualquiera de los métodos de inicialización perezosa:

QLPreviewController *previewController = [[QLPreviewController alloc] init]; previewController.dataSource = self; previewController.delegate = self; previewController.currentPreviewItemIndex = indexPath.row; [self presentModalViewController:previewController animated:YES]; [previewController release];


CGAffineTransform currentCTM = CGContextGetCTM(context); if (currentCTM.a == 1.0 && baseImage) { //Calculate ideal scale CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width; CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height; CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight); CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor); CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height); CGContextDrawImage(context, imageRect, [baseImage CGImage]); } else { @synchronized(issue) { CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1); pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true); CGContextConcatCTM(context, pdfToPageTransform); CGContextDrawPDFPage(context, pdfPage); } }