objective-c - 从 Finder 拖放到 NSTableView 怪异

标签 objective-c cocoa drag-and-drop

我试图了解如何最好地实现将文件从 Finder 拖放到 NSTableView 中,NSTableView 随后将列出这些文件。

我构建了一些test application作为试验场。

目前我有一个NSTableViewFileListController因为它是数据源。它基本上是一个 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

draggingEntereddraggingExited方法都被调用但是 prepareForDragOperationperformDragOperation不。我不明白为什么不?

接下来我想我将 NSTableView 的 ClipView 子类化。因此,使用与上面相同的代码,只需将头文件中的类类型更改为 NSClipView 我发现 prepareForDragOperationperformDragOperation现在可以按预期工作,但是 ClipView 不会突出显示。

如果我子类化 NSScrollView ,那么所有方法都会被调用,并且突出显示可以工作,但不符合要求。它非常薄,正如预期的那样围绕整个 NSTableView,而不仅仅是我想要的表格标题下方的部分。

所以我的问题是什么是正确的子类以及我需要什么方法,以便当我从 Finder 中执行拖放时,ClipView 正确突出显示并 prepareForDragOperationperformDragOperation接到电话。

还有当performDragOperation时成功后,此方法如何调用我的 FileListController 中的方法,告诉它创建一个新的 File对象并将其添加到 NSMutableArray 中?

最佳答案

回答我自己的问题。

看来子类化 NSTableView(不是 NSScrollView 或 NSClipView)是正确的方法。

在子类中包含此方法:

- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender {
return [self draggingEntered:sender];
}

解决了prepareForDragOperationperformDragOperation未被调用的问题。

为了允许您调用 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方法。

Updated example project code here.

关于objective-c - 从 Finder 拖放到 NSTableView 怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23008530/

相关文章:

ios - 专为 Iphone 6 设计的调整大小应用程序可在 iphone 5s 中正确缩放

javascript - 如何禁用/停止 jQuery 函数?

ios - 如何在 WKWebView 中禁用 iOS 11 和 iOS 12 拖放?

objective-c - QTKitServer 保留在事件监视器中

iphone - 热禁用 cocos2d 中 CCLayer 中的触摸处理

objective-c - 从 Objective C 上的另一个 JS (CSS) 文件加载 JS (CSS) 文件

ios - xcode 未获取头文件中的 typedef

objective-c - 使用 XIB 连接 NSToolBarItem

objective-c - 如何获取cocoa程序运行的路径?

javascript - 如何更改网页中下拉滚动条的初始位置?