C-Viorel
C-Viorel

Reputation: 1866

NSOpenPanel in Swift . How to open?

I have this Objective-C Code :

- (IBAction)selectFileButtonAction:(id)sender {

    //create open panel...
    NSOpenPanel* openPanel = [NSOpenPanel openPanel];
    // NSLog(@"Open Panel");
    //set restrictions / allowances...
    [openPanel setAllowsMultipleSelection: NO];
    [openPanel setCanChooseDirectories:NO];
    [openPanel setCanCreateDirectories:NO];
    [openPanel setCanChooseFiles:YES];
    //only allow images...
    [openPanel setAllowedFileTypes:[NSImage imageFileTypes]];
    //open panel as sheet on main window...
    [openPanel beginWithCompletionHandler:^(NSInteger result)  {
        if (result == NSFileHandlingPanelOKButton) {

            //get url (should only be one due to restrictions)...
            for( NSURL* URL in [openPanel URLs] ) {
               // self.roundClockView1.URL = URL ;
                _thePath = URL;
                currentSelectedFileName = [[URL path] lastPathComponent];
               // [_roundClockView1 setNeedsDisplay:1];
                [self openEditor];
            }

        }
    }];

Now I want to write this the same thing in swift. Here is what I've done until now :

@IBAction func selectAnImageFromFile(sender: AnyObject) {
    var openPanel = NSOpenPanel()
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseDirectories = false
    openPanel.canCreateDirectories = false
    openPanel.canChooseFiles = true
    openPanel.beginWithCompletionHandler(handler: (Int) -> Void)
}

and here I'm stuck. Thanks for help.

Upvotes: 27

Views: 16556

Answers (6)

water_ak47
water_ak47

Reputation: 1306

NSOpenPanel | Apple Developer Documentation https://developer.apple.com/documentation/appkit/nsopenpanel

Swift5

@objc func changeConfigFolder() {
    let openPanel = NSOpenPanel()
    openPanel.canChooseFiles = false
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseDirectories = true
    openPanel.canCreateDirectories = true
    openPanel.title = NSLocalizedString("change_the_folder", comment: "")

    openPanel.begin { [weak self] (result) -> Void in
        if result == .OK {
            let selectedPath = openPanel.url!.path
            if var userSetting = self?.userSetting {
                userSetting["save_path"] = selectedPath
                UserDefaults.standard.set(userSetting, forKey: "config")
                self?.resetStatusBar()
            }
        } else {
            openPanel.close()
        }
    }
}
    

Upvotes: 1

aaru
aaru

Reputation: 826

In SwiftUI

    struct FileView: View {
    var body: some View {
        Button("Press Me") {
            let openPanel = NSOpenPanel()
            openPanel.prompt = "Select File"
            openPanel.allowsMultipleSelection = false
                openPanel.canChooseDirectories = false
                openPanel.canCreateDirectories = false
                openPanel.canChooseFiles = true
                openPanel.begin { (result) -> Void in
                    if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
                        let selectedPath = openPanel.url!.path
                        print(selectedPath)

                    }
                }
           }
        }
     }

Upvotes: 1

ingconti
ingconti

Reputation: 11656

my two cents for swift 5.0

override func showChooseFileDialog(title: String){
    let openPanel = NSOpenPanel()
    openPanel.canChooseFiles = false
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseDirectories = false
    openPanel.canCreateDirectories = false
    openPanel.title = title

    openPanel.beginSheetModal(for:self.view.window!) { (response) in
        if response == .OK {
            let selectedPath = openPanel.url!.path
            // do whatever you what with the file path
        }
        openPanel.close()
    }
}

Upvotes: 7

Joakim Danielson
Joakim Danielson

Reputation: 52013

For Swift 4 the check of the response should be

if response == .OK { 
  ... 
}

Upvotes: 8

marknote
marknote

Reputation: 1077

Swift 4 version:

let openPanel = NSOpenPanel()
        openPanel.canChooseFiles = false
        openPanel.allowsMultipleSelection = false
        openPanel.canChooseDirectories = false
        openPanel.canCreateDirectories = false
        openPanel.title = "Select a folder"

        openPanel.beginSheetModal(for:self.view.window!) { (response) in
            if response.rawValue == NSFileHandlingPanelOKButton {
                let selectedPath = openPanel.url!.path
                // do whatever you what with the file path
            }
            openPanel.close()
        }

Upvotes: 5

Seb Jachec
Seb Jachec

Reputation: 3061

@IBAction func selectAnImageFromFile(sender: AnyObject) {
    let openPanel = NSOpenPanel()
    openPanel.allowsMultipleSelection = false
    openPanel.canChooseDirectories = false
    openPanel.canCreateDirectories = false
    openPanel.canChooseFiles = true
    openPanel.beginWithCompletionHandler { (result) -> Void in
        if result == NSFileHandlingPanelOKButton {
            //Do what you will
            //If there's only one URL, surely 'openPanel.URL'
            //but otherwise a for loop works
        }
    }
}

I'm guessing you got stuck on the completion handler part? In any case, handling the URL from the open panel should be ok from there, but comment if you want me to add more. :)

Upvotes: 50

Related Questions