5

我在编辑模式下使用 WebView。我已经从 WebUIDelegate Procotol 实现了这个方法:

- (void)webView:(WebView *)sender willPerformDragDestinationAction:(WebDragDestinationAction)action forDraggingInfo:(id < NSDraggingInfo >)draggingInfo

并用它来捕捉我的 WebView 上的元素滴。当我检测到从我的应用程序外部拖动并包含图片的文件时,我会在此方法中构建 img DOM 元素并将其添加到我的文档中。

这很好用,但正如方法名称所暗示的那样,我只被告知会发生拖动,我无法控制它。

由于 Finder 总是进行文件拖动操作,所以在编辑模式下将文件拖放到 WebView 上时通常会发生的情况是 webview 显示文件的路径。

我最终将文件路径字符串添加到我的 webview 和图像中,但我想阻止添加文本。

有没有办法在不继承 webview 的情况下配置它?

我试过了,虽然它有效,但它破坏了很多其他的东西,比如插入符号移动等。

4

3 回答 3

10

自己回答这个以获得改变!

- (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 以更改拖动粘贴板的内容,如果拖动源在我的应用程序之外并且不包含图像而只包含文件名。

于 2012-10-05T14:06:47.040 回答
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 ) {

            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 委托被调用,它已经来不及做任何事情

另外,我建议通过 UI Delegate 设置以下内容:

- (NSUInteger) webView:(WebView *)webView dragDestinationActionMaskForDraggingInfo:(id <NSDraggingInfo>)draggingInfo {

    return WebDragDestinationActionEdit;
}

好的,现在是我遇到的问题,我真的希望你能给我一个答案。当我选择一个文件时没有问题。当我选择多个文件时,我会得到它们并将它们全部正确地添加到粘贴板中。即使当我到达 (5) 的 UIDelegate 并检查 draggingPasteboard 的计数时,我也得到了预期的结果。但不幸的是,文档片段只被创建一次,同样只有一个节点被插入。

任何想法如何创建多个片段以便它们都可以插入?

先感谢您。

于 2013-03-04T22:18:20.680 回答
0

先前回复的固定版本,此代码适用于在 web 视图中拖动的多个图像。

- (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];
}
于 2013-11-05T12:14:57.230 回答