Home > Blockchain >  SwiftUI NSPathControl open finder location when clicking icons
SwiftUI NSPathControl open finder location when clicking icons

Time:11-05

I've wrapped NSPathControl for use in my Mac OS SwiftUI app but I can't work out how to make the sizes of the path smaller or how to get the individual paths to open the location in Finder when clicked.

Here is the wrapper:

struct PathView: NSViewRepresentable {
    typealias pathViewNSView = NSPathControl
    var configuration = { (view: pathViewNSView) in }
    
    func makeNSView(context: NSViewRepresentableContext<PathView>) -> NSPathControl {
        pathViewNSView()
    }
    func updateNSView(_ nsView: NSPathControl, context: NSViewRepresentableContext<PathView>) {
        configuration(nsView)
    }
}

I use the view like this:

PathView { view in
    view.url = URL(fileURLWithPath: "/Volumes/Users/myfolder", isDirectory: true)
}

I know to use NSWorkspace.shared.selectFile to open the path in Finder but not sure how to do this with the wrapped NSPathControl.

CodePudding user response:

You can use the Coordinator pattern with NSViewRepresentable:

struct PathView: NSViewRepresentable {
    var configuration = { (view: NSPathControl) in }
    
    func makeNSView(context: NSViewRepresentableContext<PathView>) -> NSPathControl {
        let pathControl = NSPathControl()
        pathControl.target = context.coordinator
        pathControl.action = #selector(Coordinator.action)
        return pathControl
    }
    func updateNSView(_ nsView: NSPathControl, context: NSViewRepresentableContext<PathView>) {
        configuration(nsView)
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
    
    class Coordinator : NSObject, NSPathControlDelegate {
        @objc func action(sender: NSPathControl) {
            if let url = sender.clickedPathItem?.url {
                print(url)
                NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: url.path)
            }
        }
    }
}

Note: I'm not actually using any NSPathControlDelegate methods -- that's just to show that it could be extended to be a delegate as well

  • Related