本文介绍了在Swift中实现拖放区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始使用Swift构建OS X应用程序,我想知道如何实现拖放区域.

I recently started using Swift to build OS X apps and I am wondering how I could implement a drag-and-drop zone.

更具体地说,我构建了一个处理图像的应用程序,但目前,用户必须手动输入输入图像的路径或使用文件选择器(这很烦人).我想改进我的应用程序,允许用户通过简单的拖放即可输入图像(我只需要检索表示图像路径的字符串)即可.

More specifically, I built an app that processes images but, for the moment, the user has to manually enter the path to the input images or use a File Chooser (which is quite annoying). I would like to improve my app allowing the user to input the images by a simple drag-and-drop (I only need to retrieve a String representing the path to the images).

我该怎么做?

推荐答案

这是我在应用程序中使用的示例.

Here's an example I'm using in an application.

  1. 如有必要,在子类声明中添加对NSDraggingDestination的一致性(NSImageView不需要,因为它已经符合协议)
  2. 声明一个可接受类型的数组(至少NSFilenamesPboardType)
  3. registerForDraggedTypes
  4. 中注册这些类型
  5. 覆盖draggingEntereddraggingUpdatedperformDragOperation
  6. 通过这些方法返回NSDragOperation
  7. draggingPasteboard数组获取文件路径
  1. Add conformance to NSDraggingDestination to your subclass declaration if necessary (not needed for NSImageView because it already conforms to the protocol)
  2. Declare an array of accepted types (at least NSFilenamesPboardType)
  3. Register these types with registerForDraggedTypes
  4. Override draggingEntered, draggingUpdated and performDragOperation
  5. Return an NSDragOperation from these methods
  6. Get the file(s) path(s) from the draggingPasteboard array

在我的示例中,我添加了一个函数来检查文件扩展名是否在我们想要的文件扩展名之中.

In my example I've added a function to check if the file extension is amongst the ones we want.

快捷键2

class MyImageView: NSImageView {

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // Declare and register an array of accepted types
        registerForDraggedTypes([NSFilenamesPboardType, NSURLPboardType, NSPasteboardTypeTIFF])
    }

    let fileTypes = ["jpg", "jpeg", "bmp", "png", "gif"]
    var fileTypeIsOk = false
    var droppedFilePath: String?

    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
        if checkExtension(sender) {
           fileTypeIsOk = true
           return .Copy
        } else {
           fileTypeIsOk = false
           return .None
        }
    }

    override func draggingUpdated(sender: NSDraggingInfo) -> NSDragOperation {
        if fileTypeIsOk {
            return .Copy
        } else {
            return .None
        }
    }

    override func performDragOperation(sender: NSDraggingInfo) -> Bool {
        if let board = sender.draggingPasteboard().propertyListForType("NSFilenamesPboardType") as? NSArray,
            imagePath = board[0] as? String {
            // THIS IS WERE YOU GET THE PATH FOR THE DROPPED FILE
            droppedFilePath = imagePath
            return true
        }
        return false
    }

    func checkExtension(drag: NSDraggingInfo) -> Bool {
        if let board = drag.draggingPasteboard().propertyListForType("NSFilenamesPboardType") as? NSArray,
            path = board[0] as? String {
            let url = NSURL(fileURLWithPath: path)
            if let fileExtension = url.pathExtension?.lowercaseString {
                return fileTypes.contains(fileExtension)
            }
        }
        return false
    }
}

快捷键3

class MyImageView: NSImageView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // Declare and register an array of accepted types
        register(forDraggedTypes: [NSFilenamesPboardType, NSURLPboardType, NSPasteboardTypeTIFF])
    }

    let fileTypes = ["jpg", "jpeg", "bmp", "png", "gif"]
    var fileTypeIsOk = false
    var droppedFilePath: String?

    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
        if checkExtension(drag: sender) {
            fileTypeIsOk = true
            return .copy
        } else {
            fileTypeIsOk = false
            return []
        }
    }

    override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
        if fileTypeIsOk {
            return .copy
        } else {
            return []
        }
    }

    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        if let board = sender.draggingPasteboard().propertyList(forType: "NSFilenamesPboardType") as? NSArray,
            imagePath = board[0] as? String {
            // THIS IS WERE YOU GET THE PATH FOR THE DROPPED FILE
            droppedFilePath = imagePath
            return true
        }
        return false
    }

    func checkExtension(drag: NSDraggingInfo) -> Bool {
        if let board = drag.draggingPasteboard().propertyList(forType: "NSFilenamesPboardType") as? NSArray,
            path = board[0] as? String {
            let url = NSURL(fileURLWithPath: path)
            if let fileExtension = url.pathExtension?.lowercased() {
                return fileTypes.contains(fileExtension)
            }
        }
        return false
    }
}

这篇关于在Swift中实现拖放区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 04:53