QuickLook 消费者作为 NSViewController 的代表 [英] QuickLook consumer as a delegate from an NSViewController

查看:23
本文介绍了QuickLook 消费者作为 NSViewController 的代表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having some problems implementing QuickLook functionality from a table in an NSView. The limited documentation on QuickLook really doesn't help at all.

通读Apple Docs(主要针对自定义生成器和插件),我最终查看了 QuickLookDownloader 示例代码.此代码基于基于文档的应用程序,但对我来说似乎是正确的方法(毕竟它是 Apple 的代码,并且在他们的项目中确实有效).

After reading through the Apple Docs (which are geared heavily towards custom generators and plugins), I ended up looking at the QuickLookDownloader sample code. This code is based upon a document-based application, but appears to be the right method for me (after all it is Apple's code and it does work in their project).

在我的实现中,我可以让 QuickLook 面板 很好地显示出来,我也可以轻松地将其关闭.但是,面板本身从不从我的 NSViewController 中调用委托方法.结果我什至从来没有显示对象,只是措辞没有选择项目".我被难住了.

In my implementation I can get the QuickLook panel to show up just fine, and I can dismiss it just as easy. However, the panel itself never calls the delegate methods from within my NSViewController. As a result I never even get to displaying objects, just the wording "No items selected". And I am stumped.

我尝试调用 setDelegate,但如果我继续沿着这条路线前进,则会收到关于即将到来的厄运的警告...

I tried calling a setDelegate, but get warned about impending doom if I continue down that route...

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

[QL] QLError(): -[QLPreviewPanel setDelegate:] called while the panel has no controller - Fix this or this will raise soon. See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.

然后,当尝试响应其中一个委托方法时,dealloc 无论如何都会发生厄运.

And then doom happens anyway with a dealloc when trying to respond to one of the delegate methods.

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

And yes I did read the header which confirms that I should be setting the delegate after I won the panel (see code below).

所以这是我的代码,它与示例代码几乎匹配,除了 a) 我从哪里获取数据(我从 NSArrayController 获取它)和 b) 我从哪里获取我的预览项目来自(我的直接来自我的模型对象 - 或者无论如何应该)

So here's my code, which pretty much matches the sample code with the exception of a) where I get my data from (I get it from an NSArrayController) and the b) where I get my preview item from (mine comes directly from my model object - or should anyway)

@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 永远不会被调用,因此代表永远不会被使用(他们绝对不会被调用).

The issue seems to be that the acceptsPreviewPanelControl never gets called, so the delegates never get used (they definitely never get called).

我确信这是我遗漏的一个简单步骤,但在剖析示例代码并浏览文档后,我没有看到答案.

I'm sure this is a simple step that I'm missing, but after dissecting the sample code and scouring over the docs I don't see the answer.

是不是因为这一切都来自 NSViewController(尽管我认为没有理由将其纳入等式)?

Is it because this is all from within an NSViewController (although I see no reason why that should even come into the equation)?

非常感谢任何和所有帮助.

Any and all help much appreciated.

解决方案更新

感谢 Peter 的观察,修复速度很快.当调试器中的错误消息与它所说的一样时,您不讨厌它吗?:-)

Thanks to Peter's observation, the fix was a quick one. Don't you hate it when the error message in the debugger means what it says? :-)

在我加载了 MyViewController 的类中,我只需要添加三行代码即可解决问题.

In my class that loaded MyViewController I simply needed to add three lines of code to fix the problem.

// 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];

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

Job done :-) Thanks Peter.

推荐答案

如果您(还不是)它的委托人,为什么希望它向您发送委托消息?如果您希望它向您发送委托消息,则需要将自己设置为其委托.

Why would you expect it to send you delegate messages if you aren't (yet) its delegate? If you want it to send you delegate messages, then you need to set yourself as its delegate.

我尝试调用 setDelegate,但如果我继续沿着这条路线前进,则会收到关于即将到来的厄运的警告...

I tried calling a setDelegate, but get warned about impending doom if I continue down that route...

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

[QL] QLError(): -[QLPreviewPanel setDelegate:] called while the panel has no controller - Fix this or this will raise soon. See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.

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

"No controller", it says. So, you need it to have a controller.

对该标题的注释,特别是关于 acceptsPreviewPanelControl: 和 QLPreviewPanel 实例方法 updateController 的注释表明,面板的控制器(如果有)是一个对象在响应者链中.因此,如果您的控制器没有成为面板的控制器,那是因为您的控制器不在响应者链中.

The comments on that header, particularly on acceptsPreviewPanelControl: and the QLPreviewPanel instance method updateController, suggest that the panel's controller, when it has one, is an object that is in the responder chain. Therefore, if your controller is not becoming the panel's controller, it's because your controller isn't in the responder chain.

所以,修复它,然后它就会工作.

So, fix that, and then it'll work.

我想你的视图控制器应该在响应者链中,只要它的视图或其任何子视图在响应者链中,但也许情况并非如此.文档没有说.如果一切都失败了,请将自己明确设置为某个视图的下一个响应者(并将其先前的下一个响应者作为您的下一个响应者),然后向预览面板发送 updateController 消息.

I would imagine that your view controller should be in the responder chain whenever its view or any subview thereof is in the responder chain, but maybe this isn't the case. The documentation doesn't say. If all else fails, set yourself as some view's next responder explicitly (and its previous next responder as your next responder), then send the preview panel an updateController message.

这篇关于QuickLook 消费者作为 NSViewController 的代表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆