dwk*_*kns 2 cocoa drag-and-drop objective-c
我试图了解如何最好地将文件从Finder拖放到NSTableView,随后将列出这些文件.
我已经建立了一个小测试应用程序作为试验场.
目前,我有一个NSTableView与FileListController它的datasourse.它基本上是一个NSMutableArray File对象.
我正在尝试找出最佳/正确的方法来实现NSTableView的拖放代码.
我的第一种方法是继承NSTableView并实现所需的方法:
TableViewDropper.h
#import <Cocoa/Cocoa.h>
@interface TableViewDropper : NSTableView
@end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
该draggingEntered和draggingExited方法都被调用,但prepareForDragOperation并performDragOperation没有.我不明白为什么不呢?
接下来我以为我将继承NSTableView的ClipView.因此,使用相同的代码上面,只是换款的头文件NSClipView类的类型我发现,prepareForDragOperation和performDragOperation现在的工作预期,但是ClipView并不突出.
如果我将NSScrollView子类化,则调用所有方法并突出显示但不是必需的.它非常薄,正如预期的那样围绕着整个NSTableView而不仅仅是我想要的表头下面的位.
所以我的问题是sublclass什么是正确的东西,我需要什么方法,以便当我从Finder执行拖放时,ClipView正确地突出显示prepareForDragOperation并被performDragOperation调用.
而且当performDragOperation成功时,该方法如何调用我的FileListController中的方法,告诉它创建一个新File对象并将其添加到NSMutableArray?
回答我自己的问题.
似乎继承NSTableView(不是NSScrollView或NSClipView)是正确的方法.
在子类中包含此方法:
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender {
return [self draggingEntered:sender];
}
Run Code Online (Sandbox Code Playgroud)
解决问题prepareForDragOperation而performDragOperation不是被调用.
要允许您在控制器类中调用方法,可以将NSTextView的delagate作为控制器.在这种情况下FileListController.
然后在performDragOperationNSTableView子类中使用类似下面的内容:
NSPasteboard *pboard = [sender draggingPasteboard];
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
id delegate = [self delegate];
if ([delegate respondsToSelector:@selector(doSomething:)]) {
[delegate performSelector:@selector(doSomething:)
withObject:filenames];
}
Run Code Online (Sandbox Code Playgroud)
这将调用doSomething控制器对象中的方法.