Swift OSX NSImageView Drag and Drop

1.5k views Asked by At

I am trying to execute an action after dropping an image on a drag and drop NSImageView but it is not working. How can I control the drag and drop operations?

I have the logoFornecedorImageView that is an NSImageView outlet. My class inherits from NSDraggingDestinatio and the dragged types are registered, but when I run the software and drag an image on it nothing happens, nothing is printed in the console.

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()
    }
}
2

There are 2 answers

0
GuiDupas On BEST ANSWER

Thanks everyone

I just performed an action and it worked fine.

@IBAction func logoFornecedorImageDropped(_ sender: NSImageView) {

        self.logoFornecedorSelecionada = true
    }
0
Clifton Labrum On

To add a little more clarity around this, you can connect a regular IBAction to your Editable NSImageView and get the image. You don't have to do any subclassing or dragging delegates.

Just do this:

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

I hope that helps. :)