我在QuickLook
从NSView
. 有限的文档QuickLook
真的没有任何帮助。
在阅读了Apple Docs(主要针对自定义生成器和插件)后,我最终查看了QuickLookDownloader 示例代码。此代码基于基于文档的应用程序,但对我来说似乎是正确的方法(毕竟它是 Apple 的代码,并且在他们的项目中确实有效)。
在我的实现中,我可以QuickLook panel
很好地显示它,并且我可以很容易地忽略它。但是,面板本身从不从 my 中调用委托方法NSViewController
。结果,我什至从来没有显示对象,只是“未选择项目”的措辞。我很难过。
我尝试调用 a setDelegate
,但如果我继续沿着那条路线前进,则会收到关于即将到来的厄运的警告......
[QL] QLError(): -[QLPreviewPanel setDelegate:] 在面板没有控制器时调用 - 修复此问题,否则此问题将很快引发。请参阅 QLPreviewPanel.h 中有关 -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl: 的注释。
然后在尝试响应委托方法之一时,无论如何都会发生厄运。
是的,我确实阅读了标题,确认我应该在赢得面板后设置委托(参见下面的代码)。
所以这是我的代码,它与示例代码几乎匹配,除了 a) 我从哪里获取数据(我从 a 获取它NSArrayController
)和 b) 我从哪里获取我的预览项目(我的直接来自我的模型对象- 或者无论如何应该)
@interface MyViewController : NSViewController
<QLPreviewPanelDataSource, QLPreviewPanelDelegate> {
QLPreviewPanel * previewPanel;
NSArrayController * myArrayController;
NSTableView * myTable;
// [...] Other instance vars
}
@implementation MyViewController
// [...] all the other methods, init, dealloc etc...
-(IBAction)togglePreviewPanel:(id)previewPanel {
if ([QLPreviewPanel sharedPreviewPanelExists] &&
[[QLPreviewPanel sharedPreviewPanel] isVisible])
{
[[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
}
else
{
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
}
}
-(BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel
{
return YES;
}
// This document is now responsible of the preview panel.
// It is allowed to set the delegate, data source and refresh panel.
-(void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
if (DEBUG) NSLog(@"QuickLook panel control did BEGIN");
previewPanel = [panel retain];
panel.delegate = self;
panel.dataSource = self;
}
// This document loses its responsisibility on the preview panel.
// Until the next call to -beginPreviewPanelControl: it must not change
// the panel's delegate, data source or refresh it.
-(void)endPreviewPanelControl:(QLPreviewPanel *)panel
{
[previewPanel release];
previewPanel = nil;
if (DEBUG) NSLog(@"QuickLook panel control did END");
}
// Quick Look panel data source
-(NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel
{
if (DEBUG) NSLog(@"QuickLook preview count called");
return [[myArrayController selectedObjects] count];
}
-(id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel
previewItemAtIndex:(NSInteger)index
{
if (DEBUG) NSLog(@"QuickLook preview selection of item called");
return [[displayAC selectedObjects] objectAtIndex:index];
}
-(BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event {
if (DEBUG) NSLog(@"QuickLook panel error handler called");
// redirect all key down events to the table view
if ([event type] == NSKeyDown) {
[myTable keyDown:event];
return YES;
}
return NO;
}
问题似乎是acceptsPreviewPanelControl
永远不会被调用,所以代表永远不会被使用(他们绝对不会被调用)。
我确定这是我缺少的一个简单步骤,但是在剖析示例代码并浏览文档后,我看不到答案。
是因为这一切都来自 NSViewController (尽管我认为没有理由将其纳入等式)?
非常感谢任何和所有帮助。
解决方案更新
多亏了彼得的观察,修复很快。当调试器中的错误消息与它所说的一样时,您不讨厌它吗?:-)
在我加载的类中,MyViewController
我只需要添加三行代码来解决问题。
// mainWindow is an IBOutlet to my window because the calling class
// is a simple object and not an NSWindowController otherwise I could
// have used `self` instead of `mainWindow`
NSResponder * aNextResponder = [mainWindow nextResponder];
[mainWindow setNextResponder:myViewControllerInstance];
[myViewControllerInstance setNextResponder:aNextResponder];
工作完成:-) 谢谢彼得。