[英]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:
方法。 我的问题:
prepareForDragOperation:
永远被召唤? 更新
我用我能找到的每种类型更新了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.