1

2 つの異なる列を含む NSTableView があります。1 つはファイル アイコンを表示する NSImageCell で、もう 1 つはテキストの右側にクイック ルック ボタンを含む NSTextFieldCell のカスタム サブクラスです。[クイック ルック] ボタンをクリックすると、次のコードが呼び出されます。

[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];

これで問題なく、空白のクイック ルック パネルに「項目が選択されていません」と表示されます。インターネットで少し調べた後、カスタム NSTableView サブクラスを実装して、Quick Look パネルのデリゲートおよびデータ ソースにしました。代理人になりたいかどうかを Quick Look が尋ねるという通知を受け取り、YES で応答します。QLPreviewPanelDataSource と QLPreviewPanelDelegate の両方にすべてのメソッドを実装していますが、実行時にコンソールに次のエラーが表示されます。

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

また、Quick Look パネルが表示されません。これはかなり奇妙に感じます。上記の最初の行は、セルがクリックされたことを知っているだけです。とにかく、カスタム テーブル ビュー サブクラスの .m ファイルは次のとおりです。

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

助けてくれてありがとう。

4

2 に答える 2

9

これは 10.6 で追加された新機能であるため、ドキュメントはこれに最適ではありません。(まあ、明らかにクラスとプロトコルの参照がありますが、私の経験では、コンパニオン ガイドは、実際のシナリオでオブジェクトがどのように使用されることを意図しているかを理解するのに役立つことが常にわかっています)。

QLPreviewPanelController プロトコル リファレンスでは、次の 3 つのメソッドが定義されています。

QLPreviewPanelController プロトコル リファレンス

クイック ルック プレビュー パネルには、このプロトコルのメソッドを実装するレスポンダー チェーンの最初のオブジェクトによって提供される項目のプレビューが表示されます。通常、これらのメソッドはウィンドウ コントローラーまたはデリゲートに実装します。パネルを制御していない場合は、プレビュー パネルの状態を変更しようとしないでください。

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

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

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

コードは次のようになると思います。

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

YES を返す以外に、そのメソッドで何もするべきではありません。acceptsPreviewPanelControl:何かが YES を返すまで、レスポンダ チェーン内のすべてのオブジェクトに送信されます。YES を返すことにより、そのオブジェクトは事実上「コントローラー」になります。後者の 2 つのメソッドは、最初のメソッドから YES が返された後、コントローラー オブジェクトで呼び出されます。したがって、メソッドでデリゲートとデータソースのみを設定する必要がありますbeginPreviewPanelControl:(その時点で、現在のコントローラーと見なされます)。

- (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.");
}
于 2010-12-25T00:49:58.410 に答える
3

初め:

-acceptsPreviewPanelControl は YES のみを返す必要があり、デリゲートとデータソースを設定しようとしません。

次に、問題は、パネルを壊す例外が発生することです。

2010-12-24 15:32:18.291 BackMeUp[4763:80f] -[NSPathStore2 stringValue]: 認識されないセレクターがインスタンス 0x5ecb10 に送信されました

例外は、次の呼び出しによって発生する可能性が非常に高いです。

[[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] stringValue]

[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow] はファイル パス (NSString のサブクラスである NSPathStore インスタンス) であるため、-stringValue には応答しません。

したがって、次のように置き換えます。

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

に:

[NSURL fileURLWithPath:[[self dataSource] tableView:self objectValueForTableColumn:fileColumn row:selectedRow]]

また、transitionImageForPreviewItem の -stringValue への呼び出しを削除します。

補足として、transitionImageForPreviewItem を呼び出すたびに画像をロードするのは最適ではないようです。他の場所で計算された画像が既にあると思います(テーブルビューに表示されています)。それを使用してみてください。

于 2010-12-25T00:47:43.277 に答える