Cocoa PDFView 仅在调整大小时显示 PDF
Posted
技术标签:
【中文标题】Cocoa PDFView 仅在调整大小时显示 PDF【英文标题】:Cocoa PDFView only displays PDF on resize 【发布时间】:2012-06-25 21:28:37 【问题描述】:如何让 PDFView 显示 PDF 而无需调整窗口大小或执行 滚动以强制重绘。
好像setNeedsDisplay
需要完成,但没有效果。
我有一个我能想到的使用 PDFView 显示 PDF 的最简单的应用程序。
基本上在Xcode中新建一个app,把代码改成:
// 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 似乎也不正确。
我为那些有时间提供帮助和/或评论的人创建了一个 Xcode project that demonstrates the issue 的 Git 存储库。
git clone git@bitbucket.org:sotapme/pdfview_open.git
使用 Xcode 版本 4.3.3 (4E3002) - 最新的 Lion。
提前感谢您的帮助。
有效的解决方案。
我找到了一个解决方案,如果我创建一个具有空实现的 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 查看器。
我把这个问题和自己的答案留给那些可能会遇到类似问题的人,希望这对他们来说是一盏昏暗的灯塔;也希望有更多可可智慧的人指出我的想法错误。
【问题讨论】:
我遇到了和你一样的问题 - PDFView 的第一页是空白的,直到你滚动或调整大小,此时它会重新绘制,并从那里继续正常工作。但是您对 PDFView 进行子类化的解决方案并不能为我解决问题。嗯。 @stevex,你有没有试过拉我的示例代码,看看它是否适合你? git clone git@bitbucket.org:sotapme/pdfview_open.git 我就此事联系了 Apple,它最终成为 10.7.4 中的一个错误,在 10.8 中已修复。解决方法是调整视图的大小,并在短时间内(即在主队列上的 dispatch_async 块中)重新调整视图的大小。 这是个好地方@stevex,谢谢。 我可以确认10.8.5下没有出现这个bug;不再需要空子类(或调整大小 + 调整大小)的解决方法。 【参考方案1】:我认为这确实是由于 PDFview 需要 setNeedsDisplay 延迟加载完成实际加载 PDF 文档造成的。
一个 hack,但是将以下内容添加到您的 - (void)windowDidLoad 方法中至少可以正确显示文档而无需调整大小。
dispatch_async(dispatch_get_main_queue(), ^
[self.myPDFView setNeedsDisplay:YES];
);
【讨论】:
感谢@Wouter。【参考方案2】:我发现在视图中设置“Wants Core Animation”标志会导致一些不稳定的行为。如果您有该设置,请尝试添加:
[pdfView setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawOnSetNeedsDisplay];
[pdfView setNeedsDisplay: YES];
加载 PDFView 的函数。
【讨论】:
有趣的是,使用我原来的“坏代码”,我查看了你所说的内容,我的 PDFView 的“核心动画层”没有勾选,所以我勾选了它开始工作了!然后我试图使它成为可能的最小变化。然后我发现了一个坏消息,它只是偶尔有效,甚至直接从查找器调用构建的应用程序,有时当它运行时它会显示 PDF,而有时它不会。即使添加您的代码也没有任何区别。【参考方案3】:这是一个假设,但可能是因为当您self.pdfView.document = document;
时,NIB 中的 PDFView 尚未实例化!
当您将消息传递给 nil
对象时,Obj-C 不会对您大喊大叫。
为了检验这个假设,你可以NSLog()
你的pdfView
看看它是否是nil
。
【讨论】:
以上是关于Cocoa PDFView 仅在调整大小时显示 PDF的主要内容,如果未能解决你的问题,请参考以下文章