cocoa、mac拖动文件url到NSView中

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

【原文地址: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






评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值