草庐IT

swift - 在 Swift 中实现拖放区域

coder 2023-07-15 原文

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

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

我该怎么做?

最佳答案

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

  1. 如有必要,将对 NSDraggingDestination 的一致性添加到您的子类声明中(NSImageView 不需要,因为它已经符合协议(protocol))
  2. 声明一组可接受的类型(至少 NSFilenamesPboardType)
  3. 使用 registerForDraggedTypes 注册这些类型
  4. 覆盖 draggingEntereddraggingUpdatedperformDragOperation
  5. 从这些方法中返回一个NSDragOperation
  6. draggingPasteboard 数组中获取文件路径

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

swift 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
    }
}

swift 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 - 在 Swift 中实现拖放区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29233247/

有关swift - 在 Swift 中实现拖放区域的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 如何在 Ruby on Rails 中实现无向图? - 2

    我需要在RubyonRails中实现无向图G=(V,E)并考虑构建一个Vertex和一个Edge模型,其中Vertex有_多条边。由于边恰好连接两个顶点,您将如何在Rails中执行此操作?您是否知道任何有助于实现此类图表的gem或库(对重新发明轮子不感兴趣;-))? 最佳答案 不知道有任何现有库在ActiveRecord之上提供图形逻辑。您可能必须实现自己的Vertex、EdgeActiveRecord支持的模型(请参阅Rails安装的rails/activerecord中的vertex.rb和edge.rb/test/fixtur

  3. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  4. ruby-on-rails - 缺失区域;使用 :region option or export region name to ENV ['AWS_REGION' ] - 2

    我知道还有其他相同的问题,但他们没有解决我的问题。我不断收到错误:Aws::Errors::MissingRegionErrorinBooksController#create,缺少区域;使用:region选项或将区域名称导出到ENV['AWS_REGION']。但是,这是我的配置开发.rb:config.paperclip_defaults={storage::s3,s3_host_name:"s3-us-west-2.amazonaws.com",s3_credentials:{bucket:ENV['AWS_BUCKET'],access_key_id:ENV['AWS_ACCE

  5. ruby - 在 Ruby 中实现 to_int 和 to_str 的后果 - 2

    我haveaclass它公开了一个字符串值和一个int值(分别是命令输出和退出代码)。除了通过to_s和to_i公开它们之外,我还使用to_str和to_int,如下所示:classStatusdefto_s@outputendalias:to_str:to_sdefto_i@status.exitstatusendalias:to_int:to_iend我的想法是能够在尽可能多的情况下使用这个对象。将其强制转换为字符串或整数会增加可用性。例如,我可以将对象与字符串连接起来:a_string="Outputwas:"+results(我想用这个作为int强制转换的例子,但是Fixnum

  6. ruby - 在 Ruby 中实现二叉树 - 2

    我一直在尝试在Ruby中实现BinaryTree类,但我得到了stackleveltoodeep错误,尽管我似乎没有在该特定代码段中使用任何递归:1.classBinaryTree2.includeEnumerable3.4.attr_accessor:value5.6.definitialize(value=nil)7.@value=value8.@left=BinaryTree.new#stackleveltoodeephere9.@right=BinaryTree.new#andhere10.end11.12.defempty?13.(self.value==nil)?true:

  7. ruby - 如何在 Ruby 中实现私有(private)内部类 - 2

    来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用

  8. ruby - 在 Ruby 中实现 Luhn 算法 - 2

    我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s

  9. ruby - 在 Ruby 中实现生产者消费者模式 - 2

    假设我有200个昂贵的方法调用(每个都有不同的参数)。出于某种原因,我可以并行执行其中的5个调用,但不能更多。我可以一次执行一个,但一次执行5个要快5倍。我想一直执行五件事。不想排五个,等五个都排完了,再排五个。如果我排队A、B、C、D、E并且C先完成,我想立即用F替换它,即使A和B还没有完成。我一直在研究这个问题,因为我可以想象它会定期发生。解决方案似乎是生产者-消费者模式,Ruby在其标准库中内置了一些用于该模式的结构(Queue和SizedQueue)。我玩过代码示例,阅读了一些文档,我想我对它有一个粗略的了解。但是我有一些问题我对我的解决方案没有信心,而且多线程的整个领域对我来

  10. ruby - 如何在 Ruby 中实现枚举器? - 2

    例如:a=[1,2,3,4,5]a.delete_if{|x|x>3}相当于:a=[1,2,3,4,5]a.delete_if.each.each.each.each{|x|x>3}我知道a.delete_if返回一个枚举器。但是当eachblock返回true时,它​​如何知道应该删除对象呢?如何手动(和在Ruby中)实现delete_if? 最佳答案 可以看看Rubinius源码:enumerablemodule这里是一个拒绝方法的例子:defrejectreturnto_enum(:reject)unlessblock_giv

随机推荐