5

我正在尝试编写一个可以打开 NSDocument 子类中的任何文件夹但无法找出正确的 Info.plist 设置的应用程序。重要的是,我的应用程序不应使用捆绑包,具有特定文件扩展名的文件夹也不能打开任何文件夹。

我尝试了什么:

  • 如果我将文档类型扩展名设置为空字符串,则文件打开面板不允许选择任何文件
  • 如果我将文档类型扩展名设置为 *,那么文件打开面板会启用所有文件,但不会启用文件夹:文件夹会像在 finder 中一样打开
  • 如果我将文件夹扩展名设置为文档类型扩展名,我可以在文件打开对话框中将文件夹作为文档打开(这是我想要的),但我将解决方案限制为具有该扩展名的文件夹
  • 通过将 OSType 设置为“fold”,将文档类型标识符或名称设置为“public.folder”等,正如我在论坛中所读到的那样,对我来说没有明显的影响。

如何在打开文件对话框中打开任何文件夹?

4

3 回答 3

6

为了完整起见,这里是@iKenndac 答案的更多详细信息:

在 IB 中检查 First Responder 的哪个方法与 File / Open... 菜单项相关联。就我而言,它是openDocument:。在 AppDelegate 中实现这个方法:

-(void)openDocument:(id)sender
{
    NSOpenPanel *panel = [NSOpenPanel openPanel];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setAllowsMultipleSelection:NO];

    [panel beginSheetModalForWindow:nil
                  completionHandler:^(NSInteger result) {
                      if (result == NSFileHandlingPanelOKButton) {
                          NSURL* selectedURL = [[panel URLs] objectAtIndex:0];
                          NSLog(@"selected URL: %@", selectedURL);
                          NSError* error = nil;
                          [[NSDocumentController sharedDocumentController] 
                              openDocumentWithContentsOfURL:selectedURL 
                                                   display:YES 
                                                     error:&error];
                      }
                  }];
}

您仍然需要在 Info.plist 中定义一个文档类型,将 Identifier (LSItemContentTypes) 字段设置为public.folder.

于 2012-12-20T14:48:00.827 回答
3

如果不编写一些自定义代码,您可能无法做到这一点。

您需要NSOpenPanel手动呈现,如下所示:

NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseFiles:NO];
[panel setCanChooseDirectories:YES];

[panel beginSheetForDirectory:nil
                         file:nil
               modalForWindow:[self window]
                modalDelegate:self
               didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
                  contextInfo:nil];

以这种方式呈现的打开面板将让用户选择他们想要的任何目录。您可以实现NSOpenPanel的委托方法来验证每个文件夹并在需要时启用/禁用。

于 2012-12-20T13:30:12.157 回答
3

正如对今天如何做到这一点的更新摘要一样,这里是我必须做的分步指南:

  1. 使用 Xcode 从Cocoa 应用程序模板创建一个应用程序项目。

  2. 选中创建基于文档的应用程序并在“文档扩展名”中留下任何建议(如果您在此处删除文件扩展名,它将拒绝启用“下一步”按钮,因此我们稍后会这样做)。

  3. 单击项目的图标,转到Info选项卡和Document Types

  4. 删除扩展字段的内容。我们的文件夹不需要特定的文件名后缀

  5. public.folder写入标识符字段。

  6. CFBundleTypeOSTypes数组中的 Additional document type properties 下添加一个条目fold 这四个小写字母)。不确定这是否有必要,但至少是正确的。

  7. 确保文档作为捆绑分发选中

  8. 为您的项目创建一个NSDocumentController包含以下方法的子类。将其命名为例如ULIFolderDocumentController

    -(void)openDocument:(id)sender
    {
        NSOpenPanel *panel = [NSOpenPanel openPanel];
        [面板 setCanChooseFiles:NO];
        [面板 setCanChooseDirectories:YES];
        [面板 setAllowsMultipleSelection:NO];

        [面板 beginWithCompletionHandler: ^( NSInteger 结果)
        {
            如果(结果 == NSFileHandlingPanelOKButton)
            {
                NSURL* selectedURL = [[panel URLs] objectAtIndex:0];
                NSLog(@"选择的 URL: %@", selectedURL);
                [self openDocumentWithContentsOfURL: selectedURL
                        显示:是
                        completionHandler: ^(NSDocument * _Nullable 文档, BOOL documentWasAlreadyOpen, NSError * _Nullable 错误)
                        {
                            NSLog(@"%spened 文档 %@ (%@)", (documentWasAlreadyOpen? "Reo" : "O"), document, error);
                        }];
            }
        }];
    }
  1. 在您的应用程序委托的-init方法中添加一行来加载您的子类,而不是NSDocumentController. 这很简单,只需请求共享对象:
    [ULIFolderDocumentController sharedDocumentController]; // 用我们的覆盖系统的 NSDocumentController。
  1. 尝试一下!:)
于 2016-04-17T12:50:24.623 回答