Cocoa QuickLook由NSTableView启动Cell [英] Cocoa QuickLook initiated by NSTableView Cell

查看:552
本文介绍了Cocoa QuickLook由NSTableView启动Cell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个NSTableView包含2个不同的列 - 一个是NSImageCell显示文件图标,第二个是NSTextFieldCell的自定义子类,包含在文本的右侧的快速查找按钮。当我点击快速查看按钮,调用以下代码:

  [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil]; 

这是它的工作,显示空白的快速查看面板说未选择项目。在我在互联网上做了一些研究之后,我实现了一个自定义NSTableView子类,成为Quick Look面板的代理和数据源。我收到通知,Quick Look询问我是否想成为代理,我回复返回是。即使我实现了QLPreviewPanelDataSource和QLPreviewPanelDelegate中的所有方法,在运行时我在控制台上得到这个错误:

  2010-12- 24 15:32:17.235 BackMeUp [4763:80f]点击:〜/ Desktop / HUDTape.mov 
2010-12-24 15:32:17.489 BackMeUp [4763:80f] [QL] QLError QLPreviewPanel setDelegate:]调用时面板没有控制器 - 修正这个或这会很快提高。
查看QLPreviewPanel.h中的注释为-acceptsPreviewPanelControl:/ - beginPreviewPanelControl:/ - endPreviewPanelControl :.
2010-12-24 15:32:17.490 BackMeUp [4763:80f] [QL] QLError(): - [QLPreviewPanel setDataSource:]调用时面板没有控制器 - 修复这个或这会很快。
查看QLPreviewPanel.h中的注释为-acceptsPreviewPanelControl:/ - beginPreviewPanelControl:/ - endPreviewPanelControl :.
2010-12-24 15:32:17.491 BackMeUp [4763:80f]我们现在可以收到QL活动。
2010-12-24 15:32:18.291 BackMeUp [4763:80f] - [NSPathStore2 stringValue]:无法识别的选择器发送到实例0x5ecb10
2010-12-24 15:32:18.292 BackMeUp [ 80f] - [NSPathStore2 stringValue]:无法识别的选择器发送到实例0x5ecb10

显示,我觉得很奇怪。上面的第一行是我知道单元格已被点击。无论如何,这里是自定义表视图子类的.m文件:

  // 
// BackupListTableView.m
// BackMeUp
//
//由Tristan Seifert于12/24/10创建。
//版权所有2010 24/7服务器。版权所有。
//

#importBackupListTableView.h


@implementation BackupListTableView

- (void)awakeFromNib {

}

//快速查看代理

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;
{
[QLPreviewPanel sharedPreviewPanel] .delegate = self;
[QLPreviewPanel sharedPreviewPanel] .dataSource = self;

NSLog(@我们现在可以接收QL事件。

return YES;
}

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
//此文档现在负责预览面板
//允许设置委托,数据源和刷新面板。
[QLPreviewPanel sharedPreviewPanel] .delegate = self;
[QLPreviewPanel sharedPreviewPanel] .dataSource = self;
}

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel
{
//此文档在预览面板上失去了责任
//直到下一次调用-beginPreviewPanelControl:它不能
//更改面板的委托,数据源或刷新它。
return;
}

//快速查看面板数据源

- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel
{
return 1 ;
}

- (id< QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index
{
int selectedRow = [self selectedRow] ;


return [NSURL URLWithString:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];
}

//快速查看面板委托

- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event
{
//将所有按键事件重定向到表视图

return NO;
}

//此委托方法提供屏幕上的矩形,面板将从中进行缩放。
- (NSRect)previewPanel:(QLPreviewPanel *)panel sourceFrameOnScreenForPreviewItem:(id< QLPreviewItem>)item
{

NSRect iconRect = [self rectOfColumn:1];
/ *
//检查图标rect是否在屏幕上可见
NSRect visibleRect = [self visibleRect];


//将图标rect转换为屏幕坐标
iconRect = [self convertRectToBase:iconRect];
iconRect.origin = [[self window] convertBaseToScreen:iconRect.origin];
* /
return iconRect;
}

//这个委托方法在表视图和预览面板之间提供一个过渡图像
- (id)previewPanel:(QLPreviewPanel *)panel transitionImageForPreviewItem:(id< ; QLPreviewItem>)item contentRect:(NSRect *)contentRect
{
int selectedRow = [self selectedRow];

NSImage * fileIcon = [[NSWorkspace sharedWorkspace] iconForFile:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];

return fileIcon;
}

@end

感谢您的帮助。 / p>

解决方案

文档不是最好的,因为它是在10.6中添加的一个新功能。 (嗯,显然有类和协议引用,但在我的经验中,我总是发现配套指南更有助于理解对象是如何在真实世界场景中使用的)。



QLPreviewPanelController协议参考定义了3种方法:


QLPreviewPanelController Protocol Reference



快速查看预览面板显示由实现此协议中方法的响应器链中的第一个对象提供的项目的预览。您通常在您的窗口控制器或委托中实现这些方法。



- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)面板;



- (BOOL)beginPreviewPanelControl:(QLPreviewPanel *)panel; p>

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel;


我猜你的代码应该看起来像这样:

   - )acceptsPreviewPanelControl:(QLPreviewPanel *)panel 
{
return YES;
}

除了返回YES,否则不应该在该方法中执行任何操作。 acceptsPreviewPanelControl:被发送到响应器链中的每个对象,直到某个返回YES。通过返回YES,该对象有效地成为控制器。后两个方法在控制器对象从第一个方法返回YES后调用。因此,您应该只在 beginPreviewPanelControl:方法中设置委托和数据源(此时您将被视为当前控制器)。

   - (void)beginPreviewPanelControl:(QLPreviewPanel *)panel 
{

此文档现在负责预览面板
//允许设置委托,数据源和刷新面板。

[QLPreviewPanel sharedPreviewPanel] .delegate = self;
[QLPreviewPanel sharedPreviewPanel] .dataSource = self;

NSLog(@我们现在可以接收QL事件。
}


I have an NSTableView that contains 2 different Columns - one is an NSImageCell that shows a file icon, and the second is a custom subclass of NSTextFieldCell that contains a quick look button on the right of the text. When I click the Quick Look button, the following code is invoked:

[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];

This does it's job and shows the blank Quick Look panel saying "No Items Selected." After I did a bit of research on the internet, I implemented a custom NSTableView subclass to be the Delegate and Data Source for the Quick Look panel. I get the notification that Quick Look asks if I want to be the delegate, and I respond with return YES. Even though I implement all methods in both QLPreviewPanelDataSource and QLPreviewPanelDelegate, at runtime I get this error on the console:

2010-12-24 15:32:17.235 BackMeUp[4763:80f] clicked: ~/Desktop/HUDTape.mov
2010-12-24 15:32:17.489 BackMeUp[4763:80f] [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:.
2010-12-24 15:32:17.490 BackMeUp[4763:80f] [QL] QLError(): -[QLPreviewPanel setDataSource:] called while the panel has no controller - Fix this or this will raise soon.
See comments in QLPreviewPanel.h for -acceptsPreviewPanelControl:/-beginPreviewPanelControl:/-endPreviewPanelControl:.
2010-12-24 15:32:17.491 BackMeUp[4763:80f] We can now receive QL Events.
2010-12-24 15:32:18.291 BackMeUp[4763:80f] -[NSPathStore2 stringValue]: unrecognized selector sent to instance 0x5ecb10
2010-12-24 15:32:18.292 BackMeUp[4763:80f] -[NSPathStore2 stringValue]: unrecognized selector sent to instance 0x5ecb10

And the Quick Look panel does not show up, which I find rather odd. The first line above is just that I know the cell has been clicked. Anyways, here is the .m file of the custom table view subclass:

//
//  BackupListTableView.m
//  BackMeUp
//
//  Created by Tristan Seifert on 12/24/10.
//  Copyright 2010 24/7 Server. All rights reserved.
//

#import "BackupListTableView.h"


@implementation BackupListTableView

- (void) awakeFromNib {

}

// Quick Look Delegates

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;
{
    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;

    NSLog(@"We can now receive QL Events.");

    return YES;
}

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
    // This document is now responsible of the preview panel
    // It is allowed to set the delegate, data source and refresh panel.
    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;
}

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel
{
    // 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.
    return;
}

// Quick Look panel data source

- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel
{
    return 1;
}

- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index
{
    int selectedRow = [self selectedRow];


    return [NSURL URLWithString:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];
}

// Quick Look panel delegate

- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event
{
    // redirect all key down events to the table view

    return NO;
}

// This delegate method provides the rect on screen from which the panel will zoom.
- (NSRect)previewPanel:(QLPreviewPanel *)panel sourceFrameOnScreenForPreviewItem:(id <QLPreviewItem>)item
{

    NSRect iconRect = [self rectOfColumn:1];
    /*
     // check that the icon rect is visible on screen
     NSRect visibleRect = [self visibleRect];


     // convert icon rect to screen coordinates
     iconRect = [self convertRectToBase:iconRect];
     iconRect.origin = [[self window] convertBaseToScreen:iconRect.origin];
     */
    return iconRect;
}

// This delegate method provides a transition image between the table view and the preview panel
- (id)previewPanel:(QLPreviewPanel *)panel transitionImageForPreviewItem:(id <QLPreviewItem>)item contentRect:(NSRect *)contentRect
{
    int selectedRow = [self selectedRow];

    NSImage *fileIcon = [[NSWorkspace sharedWorkspace] iconForFile:[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]];

    return fileIcon;
}

@end

Thanks for any help.

解决方案

The documentation isn't the best for this, since it's a new feature that was added in 10.6. (Well, there is obviously the class and protocol references, but in my experience, I've always found the Companion Guides to be more helpful in understanding how the objects are intended to be used in a real-world scenario).

The QLPreviewPanelController Protocol Reference defines 3 methods:

QLPreviewPanelController Protocol Reference

The Quick Look preview panel shows previews for items provided by the first object in the responder chain that implements the methods in this protocol. You typically implement these methods in your window controller or delegate. You should never try to modify preview panel state if you’re not controlling the panel.

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel;

- (BOOL)beginPreviewPanelControl:(QLPreviewPanel *)panel;

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel;

I'm guessing that your code should look like this:

- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel
{
    return YES;
}

You shouldn't be doing anything in that method besides returning YES. acceptsPreviewPanelControl: is sent to every object in the responder chain until something returns YES. By returning YES, that object effectively becomes "the controller". The latter 2 methods are called on the controller object after it returns YES from the first method. So you should only be setting the delegate and datasource in the beginPreviewPanelControl: method (at which time you will be regarded as the current controller).

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{

    // This document is now responsible of the preview panel
    // It is allowed to set the delegate, data source and refresh panel.

    [QLPreviewPanel sharedPreviewPanel].delegate = self;
    [QLPreviewPanel sharedPreviewPanel].dataSource = self;

    NSLog(@"We can now receive QL Events.");
}

这篇关于Cocoa QuickLook由NSTableView启动Cell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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