4

我正在尝试编写一个小型 Cocoa 应用程序。它涉及一个 NSView,我希望用户能够在其中拖动音频文件(例如,从 Finder 中)。但是,我不知道如何只允许将音频文件放入 NSView。

我设法做到了这一点,认为这会起作用:

- (id)initWithCoder:(NSCoder *)coder
{
    self=[super initWithCoder:coder];
    if ( self ) {
        NSString *myType = (__bridge NSString *)(UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, kUTTypeAudio, NULL));
        [self registerForDraggedTypes: [NSArray arrayWithObject:myType]];
    }
    return self;
}

上面的代码似乎不允许将任何文件放入 NSView。我认为这是因为myType不适用于registerForDraggedTypes.

您可以提供的任何帮助将不胜感激。提前致谢。

4

1 回答 1

5

注册类型如kUTTypeAudio不注册拖拽文件;它注册拖动的音频。它可能适用于接受从另一个应用程序拖入的任何类型的音频*,但不适用于接受文件。

您需要注册 type kUTTypeFileURL。一旦你这样做了,用户拖入的任何文件都会点亮你的拖动目标方法。在这个阶段没有办法说“我想要文件,但只有某些类型的文件”。

作为拖动目的地,您需要验证拖动(在 中draggingEntered:)。这是您测试任何文件是否为音频文件的地方。您可以选择三种方法:

  • 使用元数据框架获取每个文件的内容类型。对于没有 Spotlight 索引的卷上的任何文件,预计这将失败。
  • 使用启动服务来确定与给定文件扩展名对应的内容类型。任何没有文件扩展名的文件都会失败;只要没有文件扩展名不明确就应该可以工作(对于音频,AFAIK 来说不是问题,但对于某些扩展名,例如“dat”可能是问题)。
  • 尝试使用您的底层音频 API/库来解释每个文件,并查看它是否成功。

如果您获得其中一个文件的内容类型 (UTI),则必须查看它是否是您可以处理的类型之一。

  • 如果您只是使用 NSSound 播放音频,请使用[NSSound soundUnfilteredTypes]. 这将返回一个 UTI 数组,这样就完成了;您可以简单地将传入的 UTI 与此数组中的 UTI 进行比较(使用UTTypeEqual)。
  • 如果您使用音频文件服务(或下一个更高级别的 API,ExtAudioFile)来读取每个文件,请使用AudioFileGetGlobalInfo获取类型代码列表,然后使用UTTypeCreatePreferredIdentifierForTag将每个类型代码从 an 转换OSType为 UTI。
  • 如果您使用的是其他库,则只需查看它提供的内容即可评估它支持的类型。

*当且仅当检查传入类型是否符合您的任何注册类型而不是相等性。如果严格测试它们是否与您的注册类型相等,您将需要注册您可以处理的特定音频类型。

于 2013-08-22T22:46:49.403 回答