我试图了解如何最好地实现将文件从 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,而不仅仅是我想要的表格标题下方的部分。
所以我的问题是什么是正确的子类以及我需要什么方法,以便当我从 Finder 中执行拖放时,ClipView 正确突出显示并 prepareForDragOperation
和performDragOperation
接到电话。
还有当performDragOperation
时成功后,此方法如何调用我的 FileListController 中的方法,告诉它创建一个新的 File
对象并将其添加到 NSMutableArray 中?
最佳答案
回答我自己的问题。
看来子类化 NSTableView(不是 NSScrollView 或 NSClipView)是正确的方法。
在子类中包含此方法:
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender {
return [self draggingEntered:sender];
}
解决了prepareForDragOperation
和performDragOperation
未被调用的问题。
为了允许您调用 Controller 类中的方法,您可以将 NSTextView 的委托(delegate)作为 Controller 。在本例中FileListController
。
然后在 NSTableView 子类的 performDragOperation
中使用如下内容:
NSPasteboard *pboard = [sender draggingPasteboard];
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
id delegate = [self delegate];
if ([delegate respondsToSelector:@selector(doSomething:)]) {
[delegate performSelector:@selector(doSomething:)
withObject:filenames];
}
这将调用 Controller 对象中的doSomething
方法。
关于objective-c - 从 Finder 拖放到 NSTableView 怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23008530/