Swift OSX NSImageView 拖放

Posted

技术标签:

【中文标题】Swift OSX NSImageView 拖放【英文标题】:Swift OSX NSImageView Drag and Drop 【发布时间】:2018-02-12 23:29:09 【问题描述】:

我试图在拖放图像后执行操作NSImageView 但它不起作用。如何控制拖放操作?

我有logoFornecedorImageView,这是一个NSImageView 插座。我的类继承自NSDraggingDestinatio 并注册了拖动的类型,但是当我运行软件并在其上拖动图像时没有任何反应,控制台中也没有打印任何内容。

import Cocoa

class InserirFornecedorViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate, NSDraggingDestination 

    @IBOutlet weak var tituloJanelaLabel: NSTextField!
    @IBOutlet weak var logoFornecedorImageView: NSImageView!
    @IBOutlet weak var nomeFornecedorTextField: NSTextField!
    @IBOutlet weak var materialFornecidoTextField: NSTextField!
    @IBOutlet weak var materiaisTableView: NSTableView!
    @IBOutlet weak var indicadorAtividadeProgressIndicator: NSProgressIndicator!
    @IBOutlet weak var salvarFornercedorButton: NSButton!

    var fornecedor: Fornecedor?

    var logoFornecedorSelecionada = false

    override func viewDidLoad() 

        super.viewDidLoad()

        materiaisTableView.dataSource = self
        materiaisTableView.delegate = self

        logoFornecedorImageView.register(forDraggedTypes: logoFornecedorImageView.registeredDraggedTypes)

        fornecedor = Fornecedor()
    

    func draggingEnded(_ sender: NSDraggingInfo?) 

        print("END")
        logoFornecedorSelecionada = true
    

    func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation 

        print("ENTERED")
        return .generic
    

    func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation 

        print("UPDATED")
        return .generic
    

    func performDragOperation(_ sender: NSDraggingInfo) -> Bool 

        return true
    

    func numberOfRows(in tableView: NSTableView) -> Int 

        return fornecedor?.materiais.count ?? 0
    

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? 

        var cell: NSTableCellView?

        //if tableColumn == tableView.tableColumns[0]

        if fornecedor?.materiais.count != 0 
            let identificadorCell = "materialCellView"

            let material = fornecedor?.materiais[row]

            cell = tableView.make(withIdentifier: identificadorCell, owner: nil) as? NSTableCellView

            cell?.textField?.stringValue = material!
        

        return cell
    

    @IBAction func selecionarImagemButtonClicked(_ sender: NSButton) 

        let panel = NSOpenPanel()
        panel.canChooseFiles = true
        panel.canChooseDirectories = false
        panel.allowsMultipleSelection = false
        panel.canCreateDirectories = false
        //panel.allowedFileTypes = ["jpg","png","pct","bmp", "tiff"]
        panel.allowedFileTypes = NSImage.imageTypes()

        panel.beginSheetModal(for: view.window!)  (result) in

            if result == NSFileHandlingPanelOKButton 
                self.logoFornecedorImageView.image = NSImage(byReferencing: panel.url!)

                self.logoFornecedorSelecionada = true
            
        
    

    @IBAction func removerImagemButtonClicked(_ sender: NSButton) 

        logoFornecedorImageView.image = NSImage(named: "LogoImagemTexto")

        logoFornecedorSelecionada = false
    

    @IBAction func adicionarMaterialButton(_ sender: NSButton) 

        if materialFornecidoTextField.stringValue.isEmpty 
            mostrarErro(mensagem: "Erro de preenchimento", informativo: "Informe o material")
            materialFornecidoTextField.becomeFirstResponder()
         else 
            fornecedor?.materiais.append(materialFornecidoTextField.stringValue)

            materialFornecidoTextField.stringValue = ""

            fornecedor?.materiais.sort 
                $0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending
            
            materiaisTableView.reloadData()
        
    

    @IBAction func voltarButton(_ sender: NSButton) 

        //let usarSoftViewController = presenting as! UsarSoftViewController
        //usarSoftViewController.ativarBoxPrincipal()
        //usarSoftViewController.usuario = usuario
        //usarSoftViewController.fazerLogin()

        dismiss(self)
    

    func mostrarErro(mensagem: String, informativo: String) 

        let alert = NSAlert()
        alert.messageText = mensagem
        alert.informativeText = informativo
        alert.addButton(withTitle: "Fechar")
        alert.alertStyle = .critical
        alert.runModal()
    

【问题讨论】:

logoFornecedorImageView.register(forDraggedTypes: logoFornecedorImageView.registeredDraggedTypes) 正在重新注册已注册的类型。这没有意义。试试NSImage.imageTypes() 好的,但是还是不行。现在我改为logoFornecedorImageView.register(forDraggedTypes: NSImage.imageTypes()),当我拖放图像时,控制台中没有写入任何内容。 在图像视图上调用NSDraggingDestination 方法。在NSImageView 的子类中实现这些方法。或者,如果您只想执行和操作,则使用图像视图的操作方法,在其他编辑时也会调用该方法。图像视图必须是可编辑的。 你应该简单地继承 NSImageView 或 NSView 的拖放操作。 如何在没有子类化 NSView 的情况下对我的 ViewController 执行删除操作? 【参考方案1】:

谢谢大家

我刚刚执行了一个操作,效果很好。

@IBAction func logoFornecedorImageDropped(_ sender: NSImageView) 

        self.logoFornecedorSelecionada = true
    

【讨论】:

【参考方案2】:

为了更清楚地说明这一点,您可以将常规 IBAction 连接到您的可编辑 NSImageView 并获取图像。您不必进行任何子类化或拖动代理。

这样做:

@IBAction func imageChange(_ sender: NSImageView) 
  if let image = sender.image
    let imageData = image.tiffRepresentation 
  

我希望这会有所帮助。 :)

【讨论】:

以上是关于Swift OSX NSImageView 拖放的主要内容,如果未能解决你的问题,请参考以下文章

NSImageView 拖放问题

通过拖放文件或文件夹来启动 Swift OSX 应用程序

通过在其上拖放文件或文件夹来启动 Swift OSX 应用程序

swift 构建OSX拖放操场:将dragndrop.swift抛出到共享源中,然后测试单个playgro中的示例

将 NSImageView 添加到 NSScrollView

如何在 OSX 上拖放期间检测 META 按键