Cocoa: Drag And Drop 简单实现

先吐个槽:iOS开发在国内还是蛮火的,但是Cocoa的中文资料是在是很少,虽然国内有那么几个论坛,但是总体实力与神马StackOverflow啥的还是差多了,一些问题还是到国外的网站查才是王道。

今天遇到了这样的问题:如何实现向ImageWell中拖入文件,然后显示文件的图标并取得文件路径。

一番查找后没有太大收获,决定回归文档,如果你有同样的问题强烈建议仔细阅读一下文档中的Introduction to Drag and Drop,虽然都是英文,但是其实内容并不多,基本一个小时左右完全可以看完,另外结合一下Cocoa DragAndDrop这个官方样例(文档里也有),保证你能弄清楚Drag and Drop的实现方法。

废话不多说了,喜欢自学的就不用往下看了,懒得看文档的可以听我唠叨两句,但是还要结合文档才能真正弄懂,事先说明一下,我也只是个业余Cocoa爱好者,属于需要什么看什么的类型,所以如果犯了什么错误还请留言指正。

贴代码(点击右边箭头展开)(为了简便以下代码仅实现取得文件路径功能)

 


#import 

@protocol DragAndDropImageViewDelegate

- (void)dragFinished:(NSString *)filePath :(int) tag;

@end

@interface DragAndDropImageView : NSImageView {
	id  delegate;
}

- (id)initWithCoder:(NSCoder *)coder;

@property(nonatomic,assign) id  delegate;

@end

 


#import "DragAndDropImageView.h"

@implementation DragAndDropImageView

@synthesize delegate;

- (id)initWithCoder:(NSCoder *)coder {
	NSLog(@"initWithCoder");
	if (self = [super initWithCoder:coder]) {
		[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
	}
	return self;
}

- (NSDragOperation)draggingEntered:(id )sender {
	NSLog(@"draggingEntered");
	NSPasteboard *pboard;
	NSDragOperation sourceDragMask;

	sourceDragMask = [sender draggingSourceOperationMask];
	pboard = [sender draggingPasteboard];

	if ([[pboard types] containsObject:NSFilenamesPboardType]) {
		if (sourceDragMask & NSDragOperationLink) {
			NSLog(@"return NSDragOperationLink");
			return NSDragOperationLink;
		}
	}
	return NSDragOperationNone;
}

- (BOOL)performDragOperation:(id )sender {
	NSLog(@"performDragOperation");

	NSPasteboard *pboard;
	NSDragOperation sourceDragMask;
	int tag = [self tag];

	sourceDragMask = [sender draggingSourceOperationMask];
	pboard = [sender draggingPasteboard];

	if ([sender draggingSource] != self) {
		if ([[pboard types] containsObject:NSFilenamesPboardType]) {
			NSLog(@"ready to modify");
			NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
			NSString *filePath = [files objectAtIndex:0];
			[delegate dragFinished:filePath :tag];
			// modify here to continue
		}
	}
	return YES;
}

@end

@protocol如果没有相应需求可以忽略。

简单解释一下吧,initWithCoder是给InterfaceBuilder用的,其中的registerForDraggedTypes作用是声明Drag and Drop响应的文件类型,当有文件拖入时就会调用draggingEntered方法,该方法中判断是不是要对拖动进行响应,如果响应则继续进入performDragOperation方法,完成处理。还有些中间过程以及详细的解释,以上代码没有涉及,详情请参阅文档。

–以上–