拖放NSImage

时间:2015-05-17 15:07:12

标签: macos swift cocoa

我正在创建一个应用程序,我希望能够将图像拖动到特定的第三方应用程序Anki中。图像是从Internet加载的,因此硬盘驱动器上不存在。 API文档似乎提供了三种方法(请注意,我故意省略了使用现已弃用的API函数的替代方法):

  • 方法#1 - 方法#1适用于Anki和其他一些应用程序。 但是,它涉及在桌面上创建临时文件。这个 不太理想。

  • 方法#2 - 我根本无法使用方法#2。代码编译并运行 没有错误,但拖动图像似乎无所事事 我把图像放在哪个应用程序上。

  • 方法#3 - 方法#3适用于某些应用程序。例如,我可以拖动 将图像放入finder中的文件夹中,然后在I中创建图像 掉了它。但是,Anki不会以这种方式接受文件。

所以,我的问题是两部分:

方法#2能否正常工作?这样可以避免创建不必要的临时文件,因此非常理想。 NSImage支持NSPasteboardWriter,所以看起来应该可行。但是,我无法找到如何做到这一点的例子。

如果我必须使用方法#1,建议放置这样的临时文件的位置在哪里?如果我必须创建一个临时文件以便将图像放入我的目标应用程序,那么是推荐这样的文件的地方吗?

//
//  DraggableImageView.swift
//  Lang Search
//
//  Created by Kevin Yancey on 11/21/14.
//  Copyright (c) 2014 Kevin Yancey. All rights reserved.
//

import Foundation
import Cocoa
import AppKit

class DraggableImageView : NSImageView, NSDraggingSource {
    //Method #1 - It works, but isn't ideal yet...
    override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let imgRep = image.representations[0] as! NSBitmapImageRep;
            let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
            data.writeToFile("/Users/kpyancey/Desktop/copiedImage.png", atomically: false);
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: NSURL.fileURLWithPath("/Users/kpyancey/Desktop/copiedImage.png")!)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }

    //Method #2 - doesn't seem to work at all
    /*override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }*/
    //Method #3 - works, but not with the target application (Anki)
    /*
    override func mouseDragged(theEvent: NSEvent) {
        if let image = self.image {
            let draggingItem : NSDraggingItem = NSDraggingItem(pasteboardWriter: image)
            let draggingItems : [AnyObject] = [draggingItem]
            let draggingSession = beginDraggingSessionWithItems(draggingItems, event: theEvent, source: self)
        }
    }*/
    /*
    override func mouseDragged(theEvent: NSEvent) {
        var dragPosition = convertPoint(theEvent.locationInWindow, fromView: nil)
        dragPosition.x -= 16
        dragPosition.y -= 16
        let imageLocation = NSRect(origin: dragPosition, size: NSMakeSize(32, 32))
        self.dragPromisedFilesOfTypes(["png"], fromRect: imageLocation, source: self, slideBack: true, event: theEvent)
    }

    override func namesOfPromisedFilesDroppedAtDestination(dropDestination: NSURL) -> [AnyObject]? {
        let imgRep = image!.representations[0] as! NSBitmapImageRep;
        let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: NSDictionary() as [NSObject : AnyObject])!;
        let filePath = dropDestination.URLByAppendingPathComponent("test.png")
        data.writeToURL(filePath, atomically: false);
        return [filePath]
    }*/

    func draggingSession(session: NSDraggingSession, sourceOperationMaskForDraggingContext context: NSDraggingContext) -> NSDragOperation {
        return NSDragOperation.Copy
    }
}

1 个答案:

答案 0 :(得分:2)

显然Anki想要在粘贴板上使用网址。方法#1很棒,但使用NSCachesDirectory而不是硬编码到桌面:

NSURL* osURL = [[[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil] URLByAppendingPathComponent:@"copiedImage.png"];