NSSavePanel使用AccessoryView更改文件扩展名

El *_*ato 3 macos cocoa objective-c osx-mountain-lion

我有带有accessoryView的NSSavePanel让用户选择图形格式,以便他们可以将图像(NSImage)保存为文件.到目前为止,我有以下内容.(我正在跳过一些线来缩短它.)

- (void)exportFile {    
    NSString *filename;
    if (formatIndex1 == 0) { // Default selection by user in Preferences
        filename = @"Untitled.bmp";
    }
    else if (formatIndex1 == 1) {
        filename = @"Untitled.gif";
    }
    ...

    [panel setAllowedFileTypes:[[NSArray alloc] initWithObjects:@"bmp",@"gif",@"jpg",@"jp2",@"png",nil]];
    [panel setAllowsOtherFileTypes:NO];
    [panel setExtensionHidden:NO];
    [panel setCanCreateDirectories:YES];
    [panel setNameFieldStringValue:filename];
    [panel setAccessoryView:accessoryView1];
    [formatMenu1 setAction:@selector(dropMenuChange:)]; // formatMenu1 is NSPopUpButton
    [formatMenu1 setTarget:self];

    [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) {
        if (result == NSFileHandlingPanelOKButton) {
            // getting panel url
        }
    }];
}

-(void)dropMenuChange:(NSPopUpButton *)sender { 
    NSSavePanel *savePanel = (NSSavePanel *)[sender window];
    [savePanel setNameFieldStringValue:@"..."];
}
Run Code Online (Sandbox Code Playgroud)

我不是百分百肯定我做得对.我想要实现的是,只要用户在accessoryView的NSPopUpButton上选择文件格式,我就想将正确的扩展名附加到当前文件名.有这种神奇的方式吗?或者我是否必须以编程方式为我自己设置正确的扩展名为setNameFieldStringValue的当前文件名?

谢谢您的帮助.

小智 11

我想要实现的是,只要用户在accessoryView的NSPopUpButton上选择文件格式,我就想将正确的扩展名附加到当前文件名.有这种神奇的方式吗?

就在这里.你不需要自己动手setNameFieldStringValue:,让savePanel这样做.让我们假设fileName是一个完整的路径,/Users/hg/Pictures/2013/08/Airplanes/pic123.png并且它存在一个带有一个的savePanel的accessoryView matrix of radio buttons.每个按钮都有一个标题,如@"jpg"或@"png"或......矩阵的动作是-selectFileType:

- (IBAction) selectFileType:(id)sender
{
    [savePanel setAllowedFileTypes:@[ [[sender selectedCell] title] ] ];
    // this will set the right extension
}
Run Code Online (Sandbox Code Playgroud)

为了使用savePanel,我尝试了以下代码:

- (void) saveImage:(NSImage *) theImg
{
  savePanel = [NSSavePanel savePanel];
  NSString *imageName = [fileName lastPathComponent];
  NSString *suffix = [imageName pathExtension];
  NSString *baseName = [imageName stringByDeletingPathExtension];

  // prepare the savePanel
  [savePanel setAccessoryView:accessoryView];
  [savePanel setAllowedFileTypes:@[ suffix ] ];
  [savePanel setDirectoryURL:[NSURL fileURLWithPath:fileName]];  // convert to URL
  [savePanel setNameFieldStringValue:baseName ];  // without extension !
  // savePanel does append the suffix

  // and now start the savePanel and choose the wanted fileType
  int rtn = [savePanel runModal];   // preferred method since 10.6
  if( rtn==NSFileHandlingPanelCancelButton) return;    // do nothing

  // finally create and save the file
  if( [[[savePanel allowedFileTypes] objectAtIndex:0] isEqualToString:@"jpg" ){
      // save as jpg-file
  }
  // check for other fileTypes
  . . . 
}
Run Code Online (Sandbox Code Playgroud)

  • 这确实是正确的答案,因为 `setNameFieldStringValue:` 不会更新已经打开的 NSSavePanel 上的文件名和扩展名 (2认同)
  • 使用 setAllowedFileTypes 出人意料地有效。函数名称似乎意味着什么文件扩展名是有效的,但是我发现在数组中设置有效文件类型的列表不起作用。按照上面的建议使用单个元素的数组调用 setAllowedFileTypes 确实有效。将此标记为另一个令人困惑的 AppKit 函数,需要重做/重命名。 (2认同)

Par*_*fna 0

您必须使用正确的扩展名设置当前文件名 setNameFieldStringValue

-(void)dropMenuChange:(NSPopUpButton *)sender { 
    NSSavePanel *savePanel = (NSSavePanel *)[sender window];
    NSString *nameFieldString = [savePanel nameFieldStringValue];
    NSString *nameFieldStringWithExt = [NSString stringWithFormat:@"%@.%@",[savePanel nameFieldStringValue], popupvalue];
    [savePanel setNameFieldStringValue:nameFieldStringWithExt];
}
Run Code Online (Sandbox Code Playgroud)