Cocoa PDFView отображает PDF только при изменении размера

Как заставить PDFView отображать PDF-файл без необходимости изменять размер окна или выполнять прокрутку, чтобы принудительно перерисовать.

Как будто нужно сделать setNeedsDisplay, но это не имеет никакого эффекта.

У меня есть самое простое приложение, которое я могу придумать для отображения PDF с помощью PDFView.

В основном создайте новое приложение в Xcode и измените код следующим образом:

// AppDelegate.h
#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet PDFView *pdfView;
@end

и

// AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize pdfView = _pdfView;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"TestPage" withExtension:@"pdf"];
    PDFDocument *document = [[PDFDocument alloc] initWithURL: pdfURL];     
    self.pdfView.document = document;
}
@end

Я заметил такое же поведение в примере кода Apple PDFKitLinker2 где нужно либо прокрутить PDF-файл, либо изменить размер окна, чтобы отобразить PDF-файл.

Конечно, я новичок в мире разработки Cocoa, но я искал и не нашел действительно маленьких примеров, которые показывают, как отображать PDF. То, что я создал, кажется правильным, но у меня есть сомнения, учитывая, что даже PDFKitLinker2 не кажется правильным.

Я создал Git-репозиторий проекта Xcode, который демонстрирует проблему для тех, у кого есть время, чтобы помочь и /или комментарий.

git clone [email protected]:sotapme/pdfview_open.git

Использование Xcode версии 4.3.3 (4E3002) — последний лев.

Заранее благодарю за любую помощь.


Решение, которое работает.


Я нашел решение, в соответствии с которым, если я создам подкласс PDFView с пустой реализацией, а затем добавлю его в качестве пользовательского представления и подключим его к моему существующему IBOutlet, он будет работать.

Мне вообще смысла нет :(

//DPPDFView.h
#import <Quartz/Quartz.h>
@interface DPPDFView : PDFView
@end

и

//DPPDFView.m
#import "DPPDFView.h"
@implementation DPPDFView
@end

Документы Apple говорят:

PDFView может быть единственным классом, с которым вам нужно иметь дело для добавления функций PDF в ваше приложение. Он позволяет отображать данные PDF и позволяет пользователям выбирать содержимое, перемещаться по документу, устанавливать уровень масштабирования и копировать текстовое содержимое в монтажный стол. PDFView также отслеживает историю страниц.

Вы можете создать подкласс PDFView для создания собственного средства просмотра PDF.

Я оставляю этот вопрос и сам ответ для тех, кто может пройти мимо с подобными вопросами, надеясь, что это будет для них тусклым маяком света; Также надеюсь, что кто-то, у кого больше мудрости какао, укажет на ошибку в моем мышлении.


person sotapme    schedule 25.06.2012    source источник
comment
У меня та же проблема, что и у вас - первая страница PDFView пуста, пока вы не прокрутите или не измените размер, после чего она перерисовывается и продолжает нормально работать оттуда. Но ваше решение по созданию подклассов PDFView не исправит это для меня. Хм.   -  person stevex    schedule 29.06.2012
comment
@stevex, вы пытались извлечь мой пример кода, чтобы увидеть, работает ли он у вас? клон git [email protected]:sotapme/pdfview_open.git   -  person sotapme    schedule 30.06.2012
comment
Я связался с Apple по этому поводу, и оказалось, что это ошибка в 10.7.4, исправленная в 10.8. Обходной путь состоит в том, чтобы изменить размер представления и через некоторое время (т. е. в блоке dispatch_async в основной очереди) изменить размер представления обратно.   -  person stevex    schedule 23.10.2012
comment
Это хорошее место, @stevex, спасибо.   -  person sotapme    schedule 23.11.2012
comment
Я могу подтвердить, что ошибка не возникает под 10.8.5; обходные пути пустого подкласса (или изменение размера + изменение размера) больше не нужны.   -  person ssc    schedule 11.01.2015
comment
Кажется, эта ошибка вернулась в 10.11 (и 10.11.1). Это или что-то подобное, хотя это происходит каждый раз, когда я вызываю goToPage: now, а не только при начальной загрузке. Кто-нибудь еще нашел это также?   -  person c-had    schedule 20.11.2015
comment
@c-had, вы можете решить эту проблему @ 10.11?   -  person Parag Bafna    schedule 05.04.2016


Ответы (3)


Я решил, что это действительно вызвано тем, что PDFview требуется setNeedsDisplay после отложенной загрузки, которая фактически завершила загрузку PDF-документа.

Взлом, но добавление приведенного ниже к вашему методу - (void)windowDidLoad, по крайней мере, правильно отображает документ без необходимости изменения размера.

dispatch_async(dispatch_get_main_queue(), ^{
    [self.myPDFView setNeedsDisplay:YES];
});
person Wouter    schedule 26.10.2012
comment
Спасибо, это должно помочь @Wouter. - person sotapme; 23.11.2012

Я обнаружил, что установка флага «Хочет основная анимация» в представлении приводит к некоторому шаткому поведению. Если у вас есть этот набор, попробуйте добавить:

[pdfView setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawOnSetNeedsDisplay];
[pdfView setNeedsDisplay: YES];

к вашей функции, которая загружает PDFView.

person Dale    schedule 29.06.2012
comment
Интересно, используя свой исходный «плохой код», я изучил то, что вы сказали, и мой основной слой анимации для PDFView не отмечен галочкой, поэтому я поставил галочку, и он начал работать! Затем я попытался внести в него наименьшее возможное изменение. Затем я узнал плохую новость о том, что оно работает только изредка, даже вызывая встроенное приложение непосредственно из средства поиска, иногда, когда оно запускается, оно отображает PDF-файл, а иногда - нет. Даже добавление вашего кода ничего не изменило. - person sotapme; 30.06.2012

Это гипотеза, но это может быть потому, что когда вы self.pdfView.document = document; PDFView из NIB не был создан!

Obj-C не кричит на вас, когда вы передаете сообщения объекту nil.

Чтобы проверить эту гипотезу, вы можете NSLog() pdfView проверить, является ли он nil.

person Colas    schedule 04.04.2013