【问题标题】:Custom NSView Drag and Drop images自定义 NSView 拖放图像
【发布时间】:2015-05-07 09:12:44
【问题描述】:

我正在开发一个 OS X 应用程序,但我似乎无法让拖放工作。我用谷歌搜索了很多,但大多数关于这个主题的帖子都至少有几年的历史,而且没有一个告诉我我的想法中缺少的链接。

无论如何,这就是我想要做的。我的桌面某处有一张图片,我希望能够将其拖放到我的自定义 NSView 中。自定义视图是一个名为 CircularImageView 的自定义 NSView 的子对象,并且是层支持的,并且仅在屏幕上显示圆形图像。

代码如下:

import Cocoa
import MCTools

@objc public protocol DragAndDropCircularImageViewDelegate {
    func imageDumped(sender: AnyObject!)
}

@IBDesignable @objc public class DragAndDropCircularImageView: CircularImageView {
    // This class provides the Drag And Drop Feature to the CircularImageView Class.

    // MARK: New in this class

    var highlight: Bool = false
    public var delegate: DragAndDropCircularImageViewDelegate?

    private func registerForDraggedImages() {
        self.registerForDraggedTypes(NSImage.imageTypes())
    }

    // MARK: CircularImageView Stuff

    public override var image: NSImage? {
        didSet {
            if let newImage = image {
                delegate?.imageDumped(self)
            }
        }
    }

    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.registerForDraggedImages()
    }

    public override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        self.registerForDraggedImages()
    }

    public override func updateLayer() {
        super.updateLayer()

        if highlight == true {

        }
    }

    // MARK: NS Dragging Destination Protocol

    public override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
        // When a drag enters our drop zone.
        if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
            if ((sender.draggingSourceOperationMask().rawValue & NSDragOperation.Copy.rawValue) > 0) {
                highlight = true
                self.needsLayout = true

                sender.enumerateDraggingItemsWithOptions(.Concurrent, forView: self, classes: [NSPasteboardItem.self], searchOptions: [NSPasteboardURLReadingContentsConformToTypesKey: self], usingBlock: { (draggingItem, idx, stop) -> Void in

                    return
                })
            }
            return NSDragOperation.Copy
        }
        return NSDragOperation.None
    }

    public override func draggingExited(sender: NSDraggingInfo?) {
        // When drag exits our drop zone remove highlight of the drop zone.
        println("\(self)draggingExited")
        highlight = false
        self.needsLayout = true
    }

    public override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
        // Update view for hovering drop.
        println("\(self)prepareForDragOperation")
        highlight = false
        self.needsLayout = true
        // Can we accept the drop?
        return NSImage.canInitWithPasteboard(sender.draggingPasteboard())
    }

    public override func performDragOperation(sender: NSDraggingInfo) -> Bool {
        // Handle the drop data.
        println("\(self)performDragOperation \(sender)")
        if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
            self.image = NSImage(pasteboard: sender.draggingPasteboard())
        }
        return true
    }

    // MARK: Interface Builder Stuff
}

我看到了一些我应该使用的帖子:

self.registerForDraggedTypes([NSFilenamesPboardType])

代替:

self.registerForDraggedTypes(NSImage.imageTypes())

但这在我的情况下似乎不起作用,当我使用 NSFileNamesPboardType 时,甚至在调用任何 NSDraggingDestination 协议消息之前,我都会收到以下调试消息:

2015-05-07 11:07:19.583 CircularImageViewTest[44809:14389647] -[CircularView.DragAndDropCircularImageView copyWithZone:]: unrecognized selector sent to instance 0x608000166d80
(lldb) p 0x608000166d80
(Int) $R0 = 106102873550208

我不明白这是如何工作的。框架尝试在某个整数上复制WithZone?谁能给我解释一下?

任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: image cocoa drag-and-drop nsview


    【解决方案1】:

    好的,下面的代码有效。这都是由 draggingEntered 中的 sender.enumerateDraggingItemsWithOptions 引起的。调用 Apple 框架时出现问题。

    import Cocoa
    import MCTools
    
    @objc public protocol DragAndDropCircularImageViewDelegate {
        func imageDumped(sender: AnyObject!)
    }
    
    @IBDesignable @objc public class DragAndDropCircularImageView: CircularImageView {
        // This class provides the Drag And Drop Feature to the CircularImageView Class.
    
        // MARK: New in this class
    
        var highlight: Bool = false
        public weak var delegate: DragAndDropCircularImageViewDelegate?
    
        private func registerForDraggedImages() {
    //        self.registerForDraggedTypes(NSImage.imageTypes())
            self.registerForDraggedTypes([NSFilenamesPboardType])
        }
    
        // MARK: CircularImageView Stuff
    
        public override var image: NSImage? {
            didSet {
                if let newImage = image {
                    delegate?.imageDumped(self)
                }
            }
        }
    
        public required init?(coder: NSCoder) {
            super.init(coder: coder)
            self.registerForDraggedImages()
        }
    
        public override init(frame frameRect: NSRect) {
            super.init(frame: frameRect)
            self.registerForDraggedImages()
        }
    
        public override func updateLayer() {
            super.updateLayer()
    
            if highlight == true {
    
            }
        }
    
        // MARK: NS Dragging Destination Protocol
    
        public override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
            // When a drag enters our drop zone.
            if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
                if ((sender.draggingSourceOperationMask().rawValue & NSDragOperation.Copy.rawValue) > 0) {
                    highlight = true
                    self.needsLayout = true
                }
                return NSDragOperation.Copy
            }
            return NSDragOperation.None
        }
    
        public override func draggingExited(sender: NSDraggingInfo?) {
            // When drag exits our drop zone remove highlight of the drop zone.
            println("\(self)draggingExited")
            highlight = false
            self.needsLayout = true
        }
    
        public override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
            // Update view for hovering drop.
            println("\(self)prepareForDragOperation")
            highlight = false
            self.needsLayout = true
            // Can we accept the drop?
            return NSImage.canInitWithPasteboard(sender.draggingPasteboard())
        }
    
        public override func performDragOperation(sender: NSDraggingInfo) -> Bool {
            // Handle the drop data.
            println("\(self)performDragOperation \(sender)")
            if NSImage.canInitWithPasteboard(sender.draggingPasteboard()) {
                self.image = NSImage(pasteboard: sender.draggingPasteboard())
                self.delegate!.imageDumped(self)
            }
            return true
        }
    
        // MARK: Interface Builder Stuff
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-15
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多