Cocoa: Drag And Drop 简单实现

On 03/27/2011, in Mac Dev, by ultragtx

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

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

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

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

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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#import <Cocoa/Cocoa.h>
 
@protocol DragAndDropImageViewDelegate
 
- (void)dragFinished:(NSString *)filePath :(int) tag;
 
@end
 
@interface DragAndDropImageView : NSImageView {
	id <DragAndDropImageViewDelegate> delegate;
}
 
- (id)initWithCoder:(NSCoder *)coder;
 
@property(nonatomic,assign) id <DragAndDropImageViewDelegate> delegate;
 
@end

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
#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 <NSDraggingInfo>)sender {
	NSLog(@"draggingEntered");
	NSPasteboard *pboard;
	NSDragOperation sourceDragMask;
 
	sourceDragMask = [sender draggingSourceOperationMask];
	pboard = [sender draggingPasteboard];
 
	if ([[pboard types] containsObject:NSFilenamesPboardType]) {
		if (sourceDragMask &#038; NSDragOperationLink) {
			NSLog(@"return NSDragOperationLink");
			return NSDragOperationLink;
		}
	}
	return NSDragOperationNone;
}
 
- (BOOL)performDragOperation:(id <NSDraggingInfo>)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方法,完成处理。还有些中间过程以及详细的解释,以上代码没有涉及,详情请参阅文档。

–以上–

Tagged with:  

发表评论

电子邮件地址不会被公开。 必填项已用*标注