【发布时间】:2014-04-11 09:22:33
【问题描述】:
我正在尝试了解如何最好地将文件从 Finder 拖放到 NSTableView,该 NSTableView 随后将列出这些文件。
我建了一个小test application 作为试验场。
目前我有一个 NSTableView 和 FileListController 作为数据源。它基本上是 File 对象的 NSMutableArray。
我正在尝试找出最佳/正确的方法来实现 NSTableView 的拖放代码。
我的第一种方法是继承 NSTableView 并实现所需的方法:
TableViewDropper.h
#import <Cocoa/Cocoa.h>
@interface TableViewDropper : NSTableView
@end
TableViewDropper.m
#import "TableViewDropper.h"
@implementation TableViewDropper {
BOOL highlight;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code here.
NSLog(@"init in initWithCoder in TableViewDropper.h");
[self registerForDraggedTypes:@[NSFilenamesPboardType]];
}
return self;
}
- (BOOL)performDragOperation:(id < NSDraggingInfo >)sender {
NSLog(@"performDragOperation in TableViewDropper.h");
return YES;
}
- (BOOL)prepareForDragOperation:(id)sender {
NSLog(@"prepareForDragOperation called in TableViewDropper.h");
NSPasteboard *pboard = [sender draggingPasteboard];
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
NSLog(@"%@",filenames);
return YES;
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
highlight=YES;
[self setNeedsDisplay: YES];
NSLog(@"drag entered in TableViewDropper.h");
return NSDragOperationCopy;
}
- (void)draggingExited:(id)sender
{
highlight=NO;
[self setNeedsDisplay: YES];
NSLog(@"drag exit in TableViewDropper.h");
}
-(void)drawRect:(NSRect)rect
{
[super drawRect:rect];
if ( highlight ) {
//highlight by overlaying a gray border
[[NSColor greenColor] set];
[NSBezierPath setDefaultLineWidth: 18];
[NSBezierPath strokeRect: rect];
}
}
@end
draggingEntered 和 draggingExited 方法都会被调用,但 prepareForDragOperation 和 performDragOperation 不会。我不明白为什么不呢?
接下来我想我会将 NSTableView 的 ClipView 子类化。因此,使用与上面相同的代码并将头文件中的类类型更改为 NSClipView,我发现 prepareForDragOperation 和 performDragOperation 现在可以按预期工作,但是 ClipView 没有突出显示。
如果我将 NSScrollView 子类化,那么所有方法都会被调用并且突出显示有效,但不是必需的。它非常薄,正如预期的那样围绕整个 NSTableView 而不仅仅是我想要的表格标题下方的位。
所以我的问题是 sublclass 的正确做法是什么以及我需要什么方法以便当我从 Finder 执行拖放操作时,ClipView 会正确突出显示并调用 prepareForDragOperation 和 performDragOperation。
而且当performDragOperation 成功时,该方法如何调用我的 FileListController 中的方法,告诉它创建一个新的File 对象并将其添加到 NSMutableArray?
【问题讨论】:
-
谢谢@jsd 我已经看到了,但这对我没有帮助。我实际上是在问更多的建筑问题。子类化哪个元素等。
标签: objective-c cocoa drag-and-drop