Xcode Swift MacOS App,将文件拖放到NSTextField中 [英] Xcode Swift MacOS App, drag and drop file into NSTextField

查看:84
本文介绍了Xcode Swift MacOS App,将文件拖放到NSTextField中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为MacOS实现我的第一个应用程序,用户应输入要处理的文件路径.我在NSViewController应用程序上有一个NSTextField,我想让用户只在其中拖放一个文件,这样我就可以获取文件路径,将其打开并在NSTextField上放置一些文本以及有关该文件的信息.

你能帮我吗?我看到,如果我使NSTextField可编辑,则可以删除文件,但我不希望NSTextField可编辑(只能选择以复制粘贴信息)

谢谢!

解决方案

首先,您需要阅读此

}

I'm implementing my first app for MacOS and the user should input a file path to be processed. I have a NSTextField on my NSViewController app and I'd like to let the user just drag and drop one file there so I could get the file path, open it and put on the NSTextField some text wi the info about the file.

Can you please help me? I saw that if I make the NSTextField editable I can drop the file but I don't want the NSTextField to be editable (just selectable to copy paste info)

Thanks!

解决方案

First of all, you need to read this guide.

Second, I post here some code that I use to do something similar to what you are asking.

However, my strategy is not to subclass NSTextField but rather place this field inside an NSBox, which I subclass. This has the advantage of providing to the user some visual feedback using a focus ring.

Pay attention to performDragOperation where the string value is set via the window's controller, which then forwards it to the text field to set its string value to the path to the dropped file.

You can filter what you can accept by prepareForDragOperation. Check that too.

class DropBox: NSBox
{
     let dragType = NSPasteboard.PasteboardType(kUTTypeFileURL as String)
     var doHighlight = false

// ---------------------------------------------------------------------------------
// awakeFromNib
// ---------------------------------------------------------------------------------
override func awakeFromNib()
{
    registerForDraggedTypes([dragType])
}

// ---------------------------------------------------------------------------------
// acceptsFirstMouse
// ---------------------------------------------------------------------------------
// Accept activation click as click in window, so source doesn't have to be the
// active window
override func acceptsFirstMouse(for event: NSEvent?) -> Bool
{
    return true
}

// ---------------------------------------------------------------------------------
// draggingEntered
// ---------------------------------------------------------------------------------
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation
{
    let pasteboard = sender.draggingPasteboard
    let mask = sender.draggingSourceOperationMask
    
    if let types = pasteboard.types, types.contains(dragType)
    {
        if mask.contains(.link)
        {
            doHighlight = true
            needsDisplay = true
            return .link
        }
    }
    
    return []
}

// ---------------------------------------------------------------------------------
// draggingExited
// ---------------------------------------------------------------------------------
override func draggingExited(_ sender: NSDraggingInfo?)
{
    doHighlight = false
    needsDisplay = true
}

// ---------------------------------------------------------------------------------
// drawRect
// ---------------------------------------------------------------------------------
override func draw(_ dirtyRect: NSRect)
{
    super.draw(dirtyRect)
    
    if doHighlight {
        let rect = NSRect(x: dirtyRect.origin.x,
                          y: dirtyRect.origin.y,
                          width: NSWidth(dirtyRect),
                          height: NSHeight(dirtyRect) - NSHeight(titleRect) + 1.0)
        
        NSFocusRingPlacement.only.set()
        let contentRect = rect.insetBy(dx: 4, dy: 4)
        NSBezierPath(rect: contentRect).fill()
    }
}

// ---------------------------------------------------------------------------------
// performDragOperation
// ---------------------------------------------------------------------------------
// Method to handle drop data
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool
{
    if let source = sender.draggingSource as? NSBox {
        if source === self {
            return false
        }
    }
    
    let pasteboard = sender.draggingPasteboard
    let options = [NSPasteboard.ReadingOptionKey.urlReadingFileURLsOnly:true]
    if let urls = pasteboard.readObjects(forClasses: [NSURL.self], options: options) as? [URL],
        let controller = self.window?.delegate as? WindowController
    {
        for url in urls {
            if SchISCoreFileUtilities.isValid(url.path) {
                controller.setApplicationPath(url.path)
                return true
            }
        }
    }
    
    return false
}

// ---------------------------------------------------------------------------------
// prepareForDragOperation
// ---------------------------------------------------------------------------------
// Method to determine if we can accept the drop (filter for urls to apps)
override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool
{
    doHighlight = false
    needsDisplay = true
    let pasteboard = sender.draggingPasteboard
    
    if let types = pasteboard.types, types.contains(dragType)
    {
        let options = [NSPasteboard.ReadingOptionKey.urlReadingFileURLsOnly:true]
        if let urls = pasteboard.readObjects(forClasses: [NSURL.self], options: options) as? [URL]
        {
            for url in urls {
                if url.pathExtension == "app" {
                    return true
                }
            }
        }
    }
    
    return false
}

}

这篇关于Xcode Swift MacOS App,将文件拖放到NSTextField中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆