简体   繁体   中英

Objective-C Directory Picker ( OSX 10.7 )

So I currently have this bit of code to get a dir:

-(NSString *)get {      
  NSOpenPanel *gitDir = [NSOpenPanel openPanel];
  NSInteger *ger = [gitDir runModalForTypes:nil];
  NSString *Directory = [gitDir directory];
  return Directory;
}

But it gives me errors and says it has now been depreciated.

Is there a better way for OSX 10.7?

Whenever you see a deprecation warning you should go straight to the official documentation. In this case, the docs for NSOpenPanel say:

runModalForTypes: Displays the panel and begins a modal event loop that is terminated when the user clicks either OK or Cancel. (Deprecated in Mac OS X v10.6. Use runModal instead. You can set fileTypes using setAllowedFileTypes:.)

This is a supplement to sosborn's answer, not a replacement.

runModalForTypes: is deprecated, and the correct replacement is runModal (or setAllowedFileTypes: followed by runModal , but in this case you're passing nil for the types).

directory is also deprecated, and the correct replacement is directoryURL . (If you actually must return an NSString path rather than an NSURL , just return [[gitDir directoryURL] path] .)

However, what you're doing is asking the user to select a file, and then returning the directory that file is in, when what you really want is to ask the user to select a directory. To do that, you want to call setCanChooseFiles to NO and setCanChooseDirectories to YES , and then call URLs to get the directory the user selected.

Also, you're ignoring the result of runModal (or runModalForTypes: ). I'm sure the compiler is warning you about the unused variable "ger", and you shouldn't just ignore warnings. If the user cancels the panel, you're going to treat that as clicking OK, and select whatever directory she happened to be in when she canceled.

Here's a better implementation, which will return the URL of the selected directory, or nil if the user canceled (or somehow managed to not select anything). Again, if you need an NSString , just add a "path" call to the return statement:

-(NSURL *)get {      
   NSOpenPanel *panel = [NSOpenPanel openPanel];
   [panel setAllowsMultipleSelection:NO];
   [panel setCanChooseDirectories:YES];
   [panel setCanChooseFiles:NO];
   if ([panel runModal] != NSModalResponseOK) return nil;
   return [[panel URLs] lastObject];
}

I adapted the code by abarnert for swift. tx for the code just what I needed.

func askUserForDirectory() -> NSURL? {
        let myPanel:NSOpenPanel = NSOpenPanel()
        myPanel.allowsMultipleSelection = false
        myPanel.canChooseDirectories = true
        myPanel.canChooseFiles = false
        if ( myPanel.runModal() != NSFileHandlingPanelOKButton ) {
            return nil
        }
        return myPanel.URLs[0] as? NSURL
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM