В последнее время появилось много вопросов о рисовании PDF.
Да, вы можете легко отрисовывать PDF с помощью, UIWebView
но это не может дать производительность и функциональность, которые вы ожидаете от хорошего средства просмотра PDF.
Вы можете нарисовать страницу PDF в CALayer или в UIImage . У Apple даже есть пример кода, чтобы показать, как нарисовать большой PDF в Zoomable UIScrollview
Но одни и те же проблемы продолжают возникать.
UIImage Метод:
- PDF
UIImage
не в оптическом масштабе, а в качестве слоя. - Процессор и память бьют по генерации
UIImages
изPDFcontext
пределов / мешают использовать его для создания в реальном времени новых уровней масштабирования.
Метод CATiledLayer:
- Существуют значительные накладные расходы (время) при отрисовке полной страницы PDF на
CALayer
: рендеринг отдельных плиток (даже с настройкой tileSize) CALayers
не может быть подготовлен заранее (за кадром).
Как правило, просмотрщики PDF тоже очень много памяти. Даже контролировать использование памяти в Apple, например, масштабируемый PDF-файл.
В моем текущем проекте я разрабатываю средство просмотра PDF и отображаю UIImage
страницу в отдельном потоке (проблемы здесь тоже!) И представляю ее, когда масштаб x1. CATiledLayer
рендеринг пинает, когда масштаб> 1. iBooks использует аналогичный подход двойного дубля, как если вы прокручиваете страницы, вы можете увидеть версию страницы с более низким разрешением всего за секунду до появления четкой версии.
Я рендеринг 2 страниц с каждой стороны в фокусе, чтобы изображение PDF было готово замаскировать слой, прежде чем он начнет рисовать.
Есть ли у кого-нибудь какие-либо идеи, независимо от того, насколько они малы или очевидны, чтобы улучшить производительность / обработку памяти при рисовании PDF? или какие-то другие вопросы обсуждались здесь?
РЕДАКТИРОВАТЬ: Некоторые советы (Кредит-Люк Макнейс, VdesmedT, Мэтт Галлахер, Иоганн):
Сохраните любой носитель на диск, когда сможете.
Используйте большие tileSizes, если рендеринг на TiledLayers
инициализации часто используются массивы с объектами - заполнителей, alternitively другой подход конструкция это один
Обратите внимание, что изображения будут отображаться быстрее, чем
CGPDFPageRef
Используйте
NSOperations
или GCD & Blocks, чтобы подготовить страницы заранее.позвонить
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
перед тем,CGContextDrawPDFPage
чтобы уменьшить использование памяти при рисованииИнициирование вашего
NSOperations
с docRef - плохая идея (память), оберните docRef в синглтон.Отмена ненужных
NSOperations
Когда вы можете, особенно если они будут использовать память, остерегайтесь оставлять контексты открытыми!Перерабатывать объекты страницы и уничтожать неиспользуемые представления
Закройте все открытые контексты, как только они вам не понадобятся
при получении предупреждений памяти освободите и перезагрузите DocRef и любые страницы кэши
Другие возможности PDF:
Получение ссылок внутри PDF (и здесь и здесь )
Получение цели ссылки (Получение номера страницы из
/Dest
массива)
Получение необработанного текста (и здесь, и здесь, и здесь (с ориентацией на местоположение))
Поиск (и здесь ) (не работает со всеми PDF-файлами (некоторые просто показывают странные символы, я думаю, это проблема кодирования, но я не уверен) -Credit BrainFeeder)
CALayer и Off-Screen Rendering - рендеринг следующей страницы для быстрого / плавного отображения
Документация
- Кварц PDFObjects (Используется для мета-информации, аннотаций, превью)
- Abobe PDF Spec
Примеры проектов
- Apple / ZoomingPDF - масштабирование
UIScrollView
,CATiledLayer
- VFR / читатель - масштабирование, пейджинг,
UIScrollView
,CATiledView
- лоб / листья - пейджинг с красивыми переходами
- / Skim - все, что кажется (PDF Reader / редактор для OSX)
PSPDFKit
, оно не дешевое, но стоит: pspdfkit.comОтветы:
Я создал такое приложение, используя примерно тот же подход, за исключением:
UIImage
значок, а рисую изображение в слое при масштабировании 1. Эти плитки будут автоматически освобождаться при выдаче предупреждений памяти.Всякий раз, когда пользователь начинает масштабирование, я получаю
CGPDFPage
и отображаю его, используя соответствующий CTM. Код в- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context
это как:проблема - объект, связывающийся с
CGPDFDocumentRef
. Я синхронизирую часть, где я получаю доступ кpdfDoc
свойству, потому что я освобождаю его и воссоздаю его при получении memoryWarnings. Кажется, чтоCGPDFDocumentRef
объект делает некоторое внутреннее кэширование, от которого я не нашел, как избавиться.источник
Для простого и эффективного средства просмотра PDF, когда вам требуется только ограниченная функциональность, вы можете (iOS 4.0+) использовать платформу QuickLook:
Во-первых, вам нужно связать
QuickLook.framework
и#import <QuickLook/QuickLook.h>;
Впоследствии, в любом
viewDidLoad
или любом из ленивых методов инициализации:источник
Начиная с iOS 11 , вы можете использовать собственный фреймворк PDFKit для отображения и управления PDF-файлами.
После импорта PDFKit вы должны инициализировать
PDFView
локальный или удаленный URL-адрес и отобразить его в своем представлении.Узнайте больше о PDFKit в документации Apple Developer.
источник
источник