Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a FileDialog in SwiftUI on MacOs

In a SwiftUI app on MacOS I want to allow a users to select a file from the MacOS filesystem.
I try to use AppKits NSOpenPanel .

I tried like this, but I'm not able to create the NSViewControllerRepresentable.

struct ContentView: View {
  @State var filename = "Filename"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(filename)
      Button("select File")
      { self.showFileChooser = true
      }.sheet(isPresented: $showFileChooser)
      { FileChooser()
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct FileChooser : {
  func makeNSViewController(context: Context) -> NSOpenPanel {
    NSOpenPanel()
  }

  func updateNSViewControler(_ nsView: NSOpenPanel, context: Context) {
  }
}

Is this the correct approach?
What's wrong?

like image 241
mica Avatar asked Sep 06 '20 13:09

mica


Video Answer


1 Answers

Actually you don't need to, because NSOpenPanel is a window, not a view controller.

Here is possible approach. Tested with Xcode 11.7 / macOS 10.15.6

struct ContentView: View {
  @State var filename = "Filename"
  @State var showFileChooser = false

  var body: some View {
    HStack {
      Text(filename)
      Button("select File")
      {
        let panel = NSOpenPanel()
        panel.allowsMultipleSelection = false
        panel.canChooseDirectories = false
        if panel.runModal() == .OK {
            self.filename = panel.url?.lastPathComponent ?? "<none>"
        }
      }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}
like image 139
Asperi Avatar answered Oct 21 '22 13:10

Asperi