QuickLook使用者作为NSViewController的委托

Hoo*_*cat 10 cocoa delegates objective-c quicklook nsviewcontroller

我在QuickLook从一个表中实现功能时遇到一些问题NSView.有限的文档QuickLook确实没有任何帮助.

在阅读了Apple Docs(主要面向自定义生成器和插件)后,我最终查看了QuickLookDownloader示例代码.这段代码基于一个基于文档的应用程序,但对我来说似乎是正确的方法(毕竟它是Apple的代码,它确实在他们的项目中工作).

在我的实现中QuickLook panel,我可以让它显示得很好,我可以轻松地解雇它.但是,面板本身从不在我的内部调用委托方法NSViewController.结果我甚至都没有显示对象,只是写着"没有选择项目".我很难过.

我试着打电话给setDelegate,但如果我继续沿着那条路走下去,就会被警告即将到来的厄运......

[QL] QLError(): - [QLPreviewPanel setDelegate:]在面板没有控制器的情况下调用 - 修复此问题,否则很快就会引发此问题.请参阅QLPreviewPanel.h中的注释-acceptsPreviewPanelControl:/ - beginPreviewPanelControl:/ - endPreviewPanelControl:.

然后在尝试响应其中一个委托方法时,使用dealloc发生厄运.

是的,我确实阅读了标题,确认我应该在赢得小组后设置代表(参见下面的代码).

所以这里是我的代码,它几乎与示例代码匹配,但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;
}
Run Code Online (Sandbox Code Playgroud)

问题似乎是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];
Run Code Online (Sandbox Code Playgroud)

完成工作:-)谢谢彼得.

Pet*_*sey 6

如果您还没有代表,为什么还希望它向您发送委托消息?如果您希望它向您发送委托消息,那么您需要将自己设置为其委托.

我试着打电话给setDelegate,但如果我继续沿着那条路走下去,就会被警告即将到来的厄运......

[QL] QLError():-[QLPreviewPanel setDelegate:]在面板没有控制器的情况下调用 - 修复此问题或将很快提升.请参阅QLPreviewPanel.h中的注释-acceptsPreviewPanelControl:/ -beginPreviewPanelControl:/ -endPreviewPanelControl:.

它说:"没有控制器".所以,你需要它有一个控制器.

对该标题的评论,尤其是对acceptsPreviewPanelControl:QLPreviewPanel实例方法的评论updateController,表明面板的控制器(如果有的话)是响应者链中的对象.因此,如果您的控制器没有成为面板的控制器,那是因为您的控制器不在响应器链中.

所以,解决它,然后它会工作.

我认为只要视图或其任何子视图位于响应者链中,您的视图控制器就应该位于响应者链中,但可能情况并非如此.文档没有说.如果所有其他方法都失败了,请将您自己设置为某个视图的下一个响应者(并将其上一个下一个响应者作为您的下一个响应者),然后向预览面板发送一条updateController消息.