For a simple Swift Mac app I needed to be able to give the user a modal to browse files and then display it in a textfield. Luckily Cocoa has the NSOpenPanel which does exactly this. In this blogpost I give an example of how to use NSOpenPanel
.
Example app
For this example I have a text field and a push button. A click on the button will load the dialog and afterwards the path of file the user selects will appear in that field.
In my example the field has the name filename_field
in the ViewController
class. If you don’t know how to create outlets for interface elements, read my earlier blogpost.
“Open file…” dialog
To open the dialog we create the following function (in the ViewController
):
@IBAction func browseFile(sender: AnyObject) {
let dialog = NSOpenPanel();
dialog.title = "Choose a .txt file";
dialog.showsResizeIndicator = true;
dialog.showsHiddenFiles = false;
dialog.canChooseDirectories = true;
dialog.canCreateDirectories = true;
dialog.allowsMultipleSelection = false;
dialog.allowedFileTypes = ["txt"];
if (dialog.runModal() == NSModalResponseOK) {
let result = dialog.URL // Pathname of the file
if (result != nil) {
let path = result!.path!
filename_field.stringValue = path
}
} else {
// User clicked on "Cancel"
return
}
}
First we create a new instance of the NSOpenPanel
, on which we set some properties (like which file type we allow to be chosen or wether the user can select directories or multiple files). Then we open the actual dialog: dialog.runModal()
. We check for the return value of runModal()
so we can ignore it if the user cancelled the modal, this also works for other modals like NSSavePanel
.
We extract the URL from the model once it is closed and store it in the file_name
text field.
Toggling the dialog
The last thing we need to do is open the dialog once the user clicks on the “Select file” button. To do so we click on the little circle at the left of the function declaration and drag the line to the button.
Now we have a working OS X app with a browse file dialog. Build & run it, everything should work!