Ostatnio pojawiło się wiele pytań dotyczących rysowania plików PDF.
Tak, możesz bardzo łatwo renderować pliki PDF za pomocą, UIWebView
ale to nie daje wydajności i funkcjonalności, których można oczekiwać od dobrej przeglądarki plików PDF.
Możesz narysować stronę PDF w CALayer lub UIImage . Apple ma nawet przykładowy kod, który pokazuje, jak narysować duży plik PDF w powiększalnym widoku UIScrollview
Ale wciąż pojawiają się te same problemy.
Metoda UIImage:
- Pliki PDF
UIImage
nie są skalowane optycznie, podobnie jak podejście warstwowe. - Procesor i pamięć uderzyły przy generowaniu
UIImages
zPDFcontext
limitów / uniemożliwiają użycie go do tworzenia renderowania w czasie rzeczywistym nowych poziomów powiększenia.
Metoda CATiledLayer:
- Znaczny narzut (czas) przyciąga pełną stronę PDF do
CALayer
: poszczególne kafelki mogą być renderowane (nawet z poprawką tileSize) CALayers
nie mogę być przygotowany z wyprzedzeniem (renderowane poza ekranem).
Zasadniczo przeglądarki plików PDF są również dość obciążone pamięcią. Nawet monitoruj użycie pamięci w przykładowym pliku PDF firmy Apple.
W moim obecnym projekcie tworzę przeglądarkę plików PDF i renderuję UIImage
stronę w osobnym wątku (tutaj też są problemy!) I prezentuję ją, gdy skala wynosi x1. CATiledLayer
renderowanie kopnięć, gdy skala jest> 1. iBooks ma podobne podwójne podejście, ponieważ przewijając strony, możesz zobaczyć wersję strony w niższej rozdzielczości przez nieco mniej niż sekundę, zanim pojawi się wyraźna wersja.
Renderuję 2 strony z każdej strony strony, tak aby obraz PDF był gotowy do maskowania warstwy przed rozpoczęciem rysowania. Strony są ponownie niszczone, gdy znajdują się w odległości +2 stron od strony, na której ustawiono ostrość.
Czy ktoś ma jakieś spostrzeżenia, bez względu na to, jak małe lub oczywiste, aby poprawić wydajność / obsługę pamięci podczas rysowania plików PDF? lub jakieś inne kwestie tutaj omówione?
EDYCJA: Kilka wskazówek (Credit-Luke Mcneice, VdesmedT, Matt Gallagher, Johann):
Gdy tylko możesz, zapisz dowolny nośnik na dysku.
Użyj większego tileSizes, jeśli renderujesz na TiledLayers
init często używane tablice z obiektami zastępczymi, alternatywnie jest to inne podejście projektowe
Pamiętaj, że obrazy będą renderowane szybciej niż a
CGPDFPageRef
Użyj
NSOperations
lub GCD i bloki, aby przygotować strony z wyprzedzeniem.zadzwoń
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);
wcześniej,CGContextDrawPDFPage
aby zmniejszyć zużycie pamięci podczas rysowaniaInicjowanie twojego
NSOperations
docRef to zły pomysł (pamięć), zawiń docRef w singleton.Anuluj niepotrzebne
NSOperations
Kiedy możesz, zwłaszcza jeśli będą one korzystały z pamięci, uważaj jednak na pozostawienie otwartych kontekstów!Przetwarzaj obiekty strony i niszcz nieużywane widoki
Zamknij wszystkie otwarte konteksty, gdy tylko ich nie potrzebujesz
po otrzymaniu ostrzeżeń pamięci zwolnij i ponownie załaduj DocRef i dowolną pamięć podręczną strony
Inne funkcje PDF:
Uzyskiwanie linków w pliku PDF (i tu i tutaj )
Uzyskiwanie celu linku (Pobieranie numeru strony z
/Dest
tablicy)
Uzyskiwanie nieprzetworzonego tekstu (i tu i tutaj i tutaj (skoncentrowane na pozycjonowaniu))
Wyszukiwanie (i tutaj ) (nie działa ze wszystkimi plikami PDF (niektóre po prostu pokazują dziwne znaki, myślę, że to problem z kodowaniem, ale nie jestem pewien) -Credit BrainFeeder)
CALayer i renderowanie poza ekranem - renderowanie następnej strony w celu szybkiego / płynnego wyświetlania
Dokumentacja
- Kwarcowe obiekty PDF (używane do metadanych, adnotacji, kciuków)
- Abobe PDF Spec
Przykładowe projekty
- Apple / ZoomingPDF - powiększanie
UIScrollView
,CATiledLayer
- VFR / czytnik - powiększanie stronicowania
UIScrollView
,CATiledView
- czoło / liście - stronicowanie z ładnymi przejściami
- / skim - wszystko na co wygląda (czytnik / edytor plików PDF dla OSX)
PSPDFKit
, nie jest tanie, ale warte: pspdfkit.comOdpowiedzi:
Zbudowałem tego rodzaju aplikację, używając w przybliżeniu tego samego podejścia, z wyjątkiem:
UIImage
ale zamiast tego rysuję obraz w warstwie, gdy powiększenie wynosi 1. Te kafelki zostaną zwolnione automatycznie po wydaniu ostrzeżeń pamięci.Za każdym razem, gdy użytkownik zaczyna powiększać, uzyskuję
CGPDFPage
i renderuję go za pomocą odpowiedniego CTM. Kod w- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context
jest jak:problemem jest obiekt zawierający
CGPDFDocumentRef
. Synchronizuję część, w którejpdfDoc
uzyskuję dostęp do właściwości, ponieważ zwalniam ją i odtwarzam ponownie po otrzymaniu memoryWarnings. Wygląda na to, żeCGPDFDocumentRef
obiekt wykonuje pewne wewnętrzne buforowanie, którego nie udało mi się pozbyć.źródło
Aby uzyskać prostą i skuteczną przeglądarkę plików PDF, gdy potrzebujesz tylko ograniczonej funkcjonalności, możesz teraz (iOS 4.0+) korzystać z frameworka QuickLook:
Najpierw musisz połączyć się z
QuickLook.framework
i#import <QuickLook/QuickLook.h>;
Następnie w
viewDidLoad
dowolnej leniwej metodzie inicjalizacji:źródło
Od iOS 11 możesz używać natywnego frameworka o nazwie PDFKit do wyświetlania i manipulowania plikami PDF.
Po zaimportowaniu pliku PDFKit należy zainicjować
PDFView
lokalny lub zdalny adres URL i wyświetlić go w widoku.Przeczytaj więcej o PDFKit w dokumentacji Apple Developer.
źródło
źródło