问题描述
我最近开始使用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.
- 如有必要,在子类声明中添加对
NSDraggingDestination
的一致性(NSImageView
不需要,因为它已经符合协议) - 声明一个可接受类型的数组(至少
NSFilenamesPboardType
) - 在
registerForDraggedTypes
中注册这些类型 - 覆盖
draggingEntered
,draggingUpdated
和performDragOperation
- 通过这些方法返回
NSDragOperation
- 从
draggingPasteboard
数组获取文件路径
- Add conformance to
NSDraggingDestination
to your subclass declaration if necessary (not needed forNSImageView
because it already conforms to the protocol) - Declare an array of accepted types (at least
NSFilenamesPboardType
) - Register these types with
registerForDraggedTypes
- Override
draggingEntered
,draggingUpdated
andperformDragOperation
- Return an
NSDragOperation
from these methods - 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中实现拖放区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!