繁体   English   中英

自定义NSView拖动目标

[英]Custom NSView Drag Destination

我正在尝试创建一个简单的NSView,它允许将Finder中的文件夹拖到它上面。 文件夹路径是我希望视图作为可拖动项目接受的唯一内容。 我一直在尝试遵循Apple文档 ,但到目前为止没有任何工作。 到目前为止,我只是试图让视图适用于任何文件类型,但我似乎甚至无法做到这一点。 这是我到目前为止所拥有的:

-(id) initWithFrame:(NSRect)frameRect
{
    if (self = [super initWithFrame:frameRect])
    {
        NSLog(@"getting called");
        [self registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeString,
                                       NSPasteboardTypePDF,
                                       NSPasteboardTypeTIFF,
                                       NSPasteboardTypePNG,
                                       NSPasteboardTypeRTF,
                                       NSPasteboardTypeRTFD,
                                       NSPasteboardTypeHTML,
                                       NSPasteboardTypeTabularText,
                                       NSPasteboardTypeFont,
                                       NSPasteboardTypeRuler,
                                       NSPasteboardTypeColor,
                                       NSPasteboardTypeSound,
                                       NSPasteboardTypeMultipleTextSelection,
                                       NSPasteboardTypeFindPanelSearchOptions, nil]];
    }
    return self;
}

-(BOOL) prepareForDragOperation: (id<NSDraggingInfo>) sender
{
    NSLog(@"preparing for drag");

    return YES;
}

initWithFrame:方法被调用,但是当我尝试拖入视图时,似乎没有调用prepareForDragOperation:方法。 我的问题:

  1. 我究竟做错了什么? 为什么不准备prepareForDragOperation:永远被召唤?
  2. 要使拖动操作仅支持拖动文件夹,我需要做什么?

更新

我用我能找到的每种类型更新了registerForDraggedTypes:方法。 它现在看起来像这样:

[self registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeString,
                               NSPasteboardTypePDF,
                               NSPasteboardTypeTIFF,
                               NSPasteboardTypePNG,
                               NSPasteboardTypeRTF,
                               NSPasteboardTypeRTFD,
                               NSPasteboardTypeHTML,
                               NSPasteboardTypeTabularText,
                               NSPasteboardTypeFont,
                               NSPasteboardTypeRuler,
                               NSPasteboardTypeColor,
                               NSPasteboardTypeSound,
                               NSPasteboardTypeMultipleTextSelection,
                               NSPasteboardTypeFindPanelSearchOptions,
                               NSStringPboardType,
                               NSFilenamesPboardType,
                               NSPostScriptPboardType,
                               NSTIFFPboardType,
                               NSRTFPboardType,
                               NSTabularTextPboardType,
                               NSFontPboardType,
                               NSRulerPboardType,
                               NSFileContentsPboardType,
                               NSColorPboardType,
                               NSRTFDPboardType,
                               NSHTMLPboardType,
                               NSURLPboardType,
                               NSPDFPboardType,
                               NSVCardPboardType,
                               NSFilesPromisePboardType,
                               NSMultipleTextSelectionPboardType, nil]];

我注意到,当我将文件夹拖到视图中时,没有调用prepareForDragOperation:方法。 我错过了一步吗?

这是一个符合这些标准的简单拖放视图:

MDDragDropView.h

@interface MDDragDropView : NSView {
    BOOL        isHighlighted;
}

@property (assign, setter=setHighlighted:) BOOL isHighlighted;

@end

MDDragDropView.m

@implementation MDDragDropView

@dynamic isHighlighted;

- (void)awakeFromNib {
    NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
    [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
    NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));

    NSPasteboard *pboard = [sender draggingPasteboard];

    if ([[pboard types] containsObject:NSFilenamesPboardType]) {

        NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType];
        for (NSString *path in paths) {
            NSError *error = nil;
            NSString *utiType = [[NSWorkspace sharedWorkspace]
                                       typeOfFile:path error:&error];
            if (![[NSWorkspace sharedWorkspace] 
                      type:utiType conformsToType:(id)kUTTypeFolder]) {

                [self setHighlighted:NO];
                return NSDragOperationNone;
            }
        }
    }
    [self setHighlighted:YES];
    return NSDragOperationEvery;
}

其余的方法:

- (void)draggingExited:(id <NSDraggingInfo>)sender {
    [self setHighlighted:NO];
}


- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender  {
    return YES;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
    [self setHighlighted:NO];
    return YES;
}
- (BOOL)isHighlighted {
    return isHighlighted;
}

- (void)setHighlighted:(BOOL)value {
    isHighlighted = value;
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    if (isHighlighted) {
        [NSBezierPath setDefaultLineWidth:6.0];
        [[NSColor keyboardFocusIndicatorColor] set];
        [NSBezierPath strokeRect:self.frame];
    }
}

@end

prepareForDragOperation:没有被调用的原因是拖动目标序列遵循一组精确的步骤,如果前面的步骤没有实现,或者实现但是返回“停止拖动操作”类型的答案,则后者永远不会达到方法。 (在您的情况下,您似乎没有实现draggingEntered:方法,该方法需要返回NSDragOperationNone以外的其他NSDragOperationNone以继续执行序列)。

prepareForDragOperation:发送之前,视图首先发送一系列拖动目标消息:

单个- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender

根据从该方法返回的NSDragOperation掩码,如果在您的类中实现了以下内容,则将调用以下内容:

Multiple - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender

根据从该方法返回的NSDragOperation掩码,将调用prepareForDragOperation: .

我正在使用NSURLPboardType来注册从Finder中删除的内容(当我将文件或文件夹拖到我的应用程序时,它将它们作为URL接收)试试这个。 如果它有效,它将解决您的第二个问题:只检查URL是否是接受或拒绝丢弃的文件夹:

// if item is an NSURL * :
CFURLHasDirectoryPath((CFURLRef)item)
// returns true if item is the URL of a folder.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM