从 finder 拖放到 WebView
Posted
技术标签:
【中文标题】从 finder 拖放到 WebView【英文标题】:Drag and drop from finder to WebView 【发布时间】:2012-09-26 09:00:15 【问题描述】:我在编辑模式下使用 WebView。我已经从 WebUIDelegate Procotol 实现了这个方法:
- (void)webView:(WebView *)sender willPerformDragDestinationAction:(WebDragDestinationAction)action forDraggingInfo:(id < NSDraggingInfo >)draggingInfo
并用它来捕捉我的 WebView 上的元素滴。当我检测到从我的应用程序外部拖动并包含图片的文件时,我会在此方法中构建 img DOM 元素并将其添加到我的文档中。
这很好用,但正如方法名称所暗示的那样,我只被告知会发生拖动,我无法控制它。
由于Finder总是进行文件拖拽操作,所以在编辑模式下将文件拖放到WebView上通常会发生的是webview显示文件的路径。
我最终将文件路径字符串添加到我的 web 视图中,图像也添加了,但我想阻止添加文本。
有没有办法在不继承 webview 的情况下进行配置?
我试过了,虽然它有效,但它破坏了很多其他的东西,比如插入符号移动等。
【问题讨论】:
【参考方案1】:自己回答这个问题!
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
if ([sender draggingSource] == nil)
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] )
NSURL* fileURL;
fileURL=[NSURL URLFromPasteboard: [sender draggingPasteboard]];
NSArray *dragTypes = [NSArray arrayWithObject:NSFileContentsPboardType];
[[sender draggingPasteboard] declareTypes:dragTypes owner:nil];
NSImage *content = [[NSImage alloc] initWithContentsOfURL:fileURL];
[[sender draggingPasteboard] setData:[content TIFFRepresentation] forType:NSPasteboardTypeTIFF];
return [super performDragOperation:sender];
实际上,如果拖动源在我的应用程序之外并且不包含图像而仅包含文件名,我所做的确实是对 WebView 进行子类化并拦截 performDragOperation 以更改拖动粘贴板的内容。
【讨论】:
【参考方案2】:我遇到了同样的问题。
我发现子类化视图是将图像数据插入粘贴板的最佳位置。以下是我对多个文件的处理方式:
- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
if ( [sender draggingSource] == nil )
NSPasteboard *pboard = [sender draggingPasteboard];
NSArray *classes = @[ [NSURL class] ];
NSDictionary *options = @ NSPasteboardURLReadingFileURLsOnlyKey: [NSNumber numberWithBool:YES],
NSPasteboardURLReadingContentsConformToTypesKey: [NSImage imageTypes] ;
NSArray *fileURLs = [pboard readObjectsForClasses:classes options:options];
if ( fileURLs )
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[fileURLs count]];
for ( NSURL *fileURL in fileURLs )
[images addObject:[[NSImage alloc] initWithContentsOfURL:fileURL]];
[pboard declareTypes:[NSImage imageTypes] owner:nil];
[pboard clearContents]; [pboard writeObjects:images];
return [super performDragOperation:sender];
我注意到的是以下顺序: 1、WebView捕捉拖拽操作。 2. 内部WebCore创建的文档片段 3. 节点被插入到 DOMRange 4. 编辑委托被调用 5. 最后调用 UI Delegate 时已经来不及做任何事情了
另外,我建议通过 UI Delegate 设置以下内容:
- (NSUInteger) webView:(WebView *)webView dragDestinationActionMaskForDraggingInfo:(id <NSDraggingInfo>)draggingInfo
return WebDragDestinationActionEdit;
好的,现在我遇到了 ISSUE,我真的希望你能给我一个答案。当我选择一个文件时没有问题。当我选择多个文件时,我会得到它们并将它们全部正确地添加到粘贴板中。即使当我到达 (5) 的 UIDelegate 并检查 draggingPasteboard 的计数时,我也得到了预期的结果。但不幸的是,文档片段只被创建一次,同样只有一个节点被插入。
任何想法如何创建多个片段以便它们都可以插入?
提前谢谢你。
【讨论】:
【参考方案3】:之前回复的固定版本,此代码适用于在网络视图中拖动的多个图像。
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
if ( [sender draggingSource] == nil )
NSPasteboard *pboard = [sender draggingPasteboard];
NSArray *classes = @[ [NSURL class] ];
NSDictionary *options = @ NSPasteboardURLReadingFileURLsOnlyKey: [NSNumber numberWithBool:YES],
NSPasteboardURLReadingContentsConformToTypesKey: [NSImage imageTypes] ;
NSArray *fileURLs = [pboard readObjectsForClasses:classes options:options];
if(fileURLs)
NSArray* filenames = [pboard propertyListForType: NSFilenamesPboardType];
NSMutableString* html = [NSMutableString string];
for(NSString* filename in filenames)
[html appendFormat: @"<img src=\"%@\"/>", [[[NSURL alloc] initFileURLWithPath: filename] absoluteString]];
[pboard declareTypes: [NSArray arrayWithObject: NSHTMLPboardType] owner: self];
[pboard setString: html forType: NSHTMLPboardType];
return [super performDragOperation:sender];
【讨论】:
以上是关于从 finder 拖放到 WebView的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac OS X 10.5 中处理从 Finder 中的多个文件拖放?