2012-04-25 49 views
10

Tôi đang cố gắng triển khai kéo và thả từ Trình tìm kiếm vào NSTableView của ứng dụng của tôi. Thiết lập sử dụng một NSTableView, một bộ điều khiển mảng hoạt động như một nguồn dữ liệu bằng cách sử dụng các kết buộc Cocoa tới một kho lưu trữ dữ liệu lõi.NSTableView và kéo và thả từ Trình tìm kiếm

tôi đã làm như sau, về cơ bản sau bài đăng trên blog khác nhau tôi tìm thấy trên SO và các trang web khác:

Trong awakeFromNib của bộ điều khiển quan điểm của tôi tôi gọi:

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

Tôi subclassed NSArrayController và bổ sung như sau các phương thức cho lớp con của tôi (lý do cho phân lớp là trình điều khiển mảng cần phải được thông báo về việc thả vì nó hoạt động như nguồn dữ liệu của chế độ xem bảng):

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

Việc triển khai của tôi đối với những điều trên hiện chỉ ghi vào nhật ký và sau đó trả về giá trị Boolean YES.

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

Trong IB tôi có bộ điều khiển mảng trỏ tới lớp con NSArrayController tùy chỉnh của tôi.

Kết quả: không có gì. Khi tôi kéo PNG từ màn hình sang chế độ xem bảng của mình, không có gì xảy ra và tệp tin vui vẻ bị trả về nguồn gốc của nó. Tôi phải làm điều gì đó sai trái nhưng không hiểu điều gì. Tôi làm sai ở đâu?

Trả lời

17

Kéo từ Trình tìm kiếm luôn là kéo tệp, không phải là kéo hình ảnh. Bạn sẽ cần hỗ trợ kéo URL từ Trình tìm kiếm.

Để làm điều đó, bạn cần phải tuyên bố rằng bạn muốn loại URL:

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

Bạn có thể xác nhận các tập tin như vậy:

- (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; 
} 

Sau đó, bạn sẽ cần phải trích xuất URL một lần nữa khi phương thức tableView:acceptDrop:row:dropOperation: được gọi, hãy tạo hình ảnh từ URL và sau đó thực hiện điều gì đó với hình ảnh đó.

Mặc dù bạn đang sử dụng kết buộc Cocoa, bạn vẫn cần chỉ định và triển khai đối tượng làm datasource trong số NSTableView nếu bạn muốn sử dụng các phương pháp kéo. Phân lớp NSTableView sẽ không hoạt động tốt vì phương pháp nguồn dữ liệu không được triển khai trong NSTableView.

Bạn chỉ cần triển khai các phương pháp liên quan đến kéo trong đối tượng nguồn dữ liệu của mình, không phải các phương thức cung cấp dữ liệu bảng khi bạn đang sử dụng các ràng buộc để thực hiện điều đó. Bạn có trách nhiệm thông báo cho bộ điều khiển mảng về kết quả của việc thả bằng cách gọi một trong các phương thức NSArrayController chẳng hạn như insertObject:atArrangedObjectIndex: hoặc bằng cách sửa đổi mảng sao lưu bằng cách sử dụng các phương thức truy cập tuân thủ Mã hóa giá trị khóa.

+0

Cảm ơn, nhưng chế độ xem bảng vẫn không chấp nhận bất kỳ thao tác kéo/thả nào. Bất kỳ tập tin tôi kéo từ Finder bị trả lại .... Tôi sử dụng kết buộc Cocoa để đính kèm bảng vào nguồn dữ liệu của nó. – Roger

+0

Tôi đã cập nhật câu trả lời của mình. Bạn vẫn cần triển khai đối tượng nguồn dữ liệu. –