11

Finder からアプリの NSTableView にドラッグ アンド ドロップを実装しようとしています。セットアップではNSTableView、Core Data ストアへの Cocoa バインディングを使用してデータソースとして機能するアレイ コントローラーを使用します。

基本的に、SOや他のサイトで見つけたさまざまなブログ投稿に従って、次のことを行いました。

awakeFromNib私のView Controllerの中で、私は次のように呼びます:

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObjects: NSPasteboardTypePNG, nil]];

NSArrayController をサブクラス化し、サブクラスに次のメソッドを追加しました (サブクラス化の理由は、配列コントローラーがテーブル ビューのデータソースとして機能するため、ドロップを通知する必要があるためです)。

- (BOOL) tableView: (NSTableView *) aTableView acceptDrop: (id < NSDraggingInfo >) info row: (NSInteger) row dropOperation: (NSTableViewDropOperation)operation

上記の私の実装は現在、ログに書き込むだけで、ブール値の YES を返します。

- (NSDragOperation) tableView: (NSTableView *) aTableView validateDrop: (id < NSDraggingInfo >) info proposedRow: (NSInteger) row proposedDropOperation: (NSTableViewDropOperation) operation

IB では、カスタム NSArrayController サブクラスを指しているアレイ コントローラーがあります。

結果: 何もありません。デスクトップから PNG をテーブル ビューにドラッグしても、何も起こらず、ファイルは問題なく元の場所に戻ります。私は何か間違ったことをしているに違いありませんが、何がわかりません。どこが間違っていますか?

4

1 に答える 1

20

Finder からのドラッグは、画像のドラッグではなく、常にファイルのドラッグです。Finder からの URL のドラッグをサポートする必要があります。

そのためには、URL タイプが必要であることを宣言する必要があります。

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObject:(NSString*)kUTTypeFileURL]];

次のようにファイルを検証できます。

 - (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id < NSDraggingInfo >)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation
{
    //get the file URLs from the pasteboard
    NSPasteboard* pb = info.draggingPasteboard;

    //list the file type UTIs we want to accept
    NSArray* acceptedTypes = [NSArray arrayWithObject:(NSString*)kUTTypeImage];

    NSArray* urls = [pb readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]]
     options:[NSDictionary dictionaryWithObjectsAndKeys:
                [NSNumber numberWithBool:YES],NSPasteboardURLReadingFileURLsOnlyKey,
                acceptedTypes, NSPasteboardURLReadingContentsConformToTypesKey,
                nil]];

    //only allow drag if there is exactly one file
    if(urls.count != 1)
        return NSDragOperationNone;

    return NSDragOperationCopy;
}

次に、メソッドが呼び出されたときに URL を再度抽出し、URLtableView:acceptDrop:row:dropOperation:から画像を作成して、その画像で何かを行う必要があります。

Cocoa バインディングを使用していても、ドラッグ メソッドを使用する場合datasourceは、オブジェクトを として割り当てて実装する必要があります。NSTableViewではデータソース メソッドが実装されていないため、サブクラス化は役に立ちNSTableViewませんNSTableView

バインディングを使用してテーブル データを提供するメソッドではなく、データソース オブジェクトにドラッグ関連のメソッドを実装するだけで済みます。NSArrayControllerなどのメソッドのいずれかを呼び出すかinsertObject:atArrangedObjectIndex:、Key-Value Coding 準拠のアクセサー メソッドを使用してバッキング配列を変更することにより、ドロップの結果を配列コントローラーに通知するのはユーザーの責任です。

于 2012-04-25T04:57:03.390 に答える