【原文地址:cocoa、mac拖动文件url到NSView中】
【作者:chenghxc】
【Demo:源码下载地址】
在项目开发中,有时候需要从外部添加文件或url等数据到程序中,可以通过菜单中的导入项打开文件路径导入,也可以通过拖动外部文件到程序中直接导入。
本博文以如何拖动本地文件为例,介绍如何拖动外部文件到程序中。当然如果你想拖动url链接到程序中,只要修改本博文提供的源码中的相应参数就可以实现了。
下面是实现的步骤:
第一步:我们需要创建一个可以接收拖动事件的View,这里命名为DragDropView,这个View继承于NSView,并且我们在View中实现了代理
DragDropViewDelegate,用于返回接收到的数据:
#import <Cocoa/Cocoa.h>
@protocol DragDropViewDelegate;
@interface DragDropView : NSView
@property (assign) IBOutlet id<DragDropViewDelegate> delegate;
@end
@protocol DragDropViewDelegate <NSObject>
-(void)dragDropViewFileList:(NSArray*)fileList;
@end
#import "DragDropView.h"
@implementation DragDropView
@synthesize delegate = _delegate;
- (void)dealloc {
[self setDelegate:nil];
[super dealloc];
}
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
/***
第一步:帮助view注册拖动事件的监听器,可以监听多种数据类型,这里只列出比较常用的:
NSStringPboardType 字符串类型
NSFilenamesPboardType 文件
NSURLPboardType url链接
NSPDFPboardType pdf文件
NSHTMLPboardType html文件
***/
//这里我们只添加对文件进行监听,如果拖动其他数据类型到view中是不会被接受的
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
}
return self;
}
/***
第二步:当拖动数据进入view时会触发这个函数,我们可以在这个函数里面判断数据是什么类型,来确定要显示什么样的图标。比如接受到的数据是我们想要的NSFilenamesPboardType文件类型,我们就可以在鼠标的下方显示一个“+”号,当然我们需要返回这个类型NSDragOperationCopy。如果接受到的文件不是我们想要的数据格式,可以返回NSDragOperationNone;这个时候拖动的图标不会有任何改变。
***/
-(NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender{
NSPasteboard *pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
return NSDragOperationCopy;
}
return NSDragOperationNone;
}
/***
第三步:当在view中松开鼠标键时会触发以下函数,我们可以在这个函数里面处理接受到的数据
***/
-(BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender{
// 1)、获取拖动数据中的粘贴板
NSPasteboard *zPasteboard = [sender draggingPasteboard];
// 2)、从粘贴板中提取我们想要的NSFilenamesPboardType数据,这里获取到的是一个文件链接的数组,里面保存的是所有拖动进来的文件地址,如果你只想处理一个文件,那么只需要从数组中提取一个路径就可以了。
NSArray *list = [zPasteboard propertyListForType:NSFilenamesPboardType];
// 3)、将接受到的文件链接数组通过代理传送
if(self.delegate && [self.delegate respondsToSelector:@selector(dragDropViewFileList:)])
[self.delegate dragDropViewFileList:list];
return YES;
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
}
@end
第二步: 在AppDelegate中实现DragDropView的代理
#import <Cocoa/Cocoa.h>
#import "DragDropView.h"
/***
第四步:添加DragDropView的代理,接受返回的filelist
***/
@interface AppDelegate : NSObject <NSApplicationDelegate,DragDropViewDelegate>
@property (assign) IBOutlet NSWindow *window;
@end
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
/***
第五步:实现dragdropview的代理函数,如果有数据返回就会触发这个函数
***/
-(void)dragDropViewFileList:(NSArray *)fileList{
//如果数组不存在或为空直接返回不做处理(这种方法应该被广泛的使用,在进行数据处理前应该现判断是否为空。)
if(!fileList || [fileList count] <= 0)return;
//在这里我们将遍历这个数字,输出所有的链接,在后台你将会看到所有接受到的文件地址
for (int n = 0 ; n < [fileList count] ; n++) {
NSLog(@">>> %@",[fileList objectAtIndex:n]);
}
}
/***
第六步:在MainMenu.xib中添加一个CustomView,将类型改为DragDropView,并将DragDropView的delegate指定到AppDelegate中
***/
@end
第三步: 在MainMenu.xib 中添加一个CustomView ,将类型改为DragDropView ,并将DragDropView 的delegate 指定到AppDelegate 中

本文介绍了在Mac应用程序中如何实现在NSView上拖放本地文件,通过自定义DragDropView并实现拖放事件代理,允许用户直接从桌面或其他位置拖入文件URL进行导入。

788

被折叠的 条评论
为什么被折叠?



