macOS文件选择对话框NSOpenPanel
macOS文件选择对话框NSOpenPanel

macOS文件选择对话框NSOpenPanel

NSOpenPanel 是 macOS 框架(AppKit)中提供的一个系统级文件选择对话框类,专用于让用户选择文件或文件夹。

可以把它理解为 macOS 上的标准 “打开文件…” 弹窗。

基本用途

用于在 macOS 应用中,让用户:

1、选择一个或多个文件。

2、选择一个或多个文件夹。

3、限制选择的类型(如只选图片)。

4、获取用户选中的文件路径。

使用示例

let panel = NSOpenPanel()
panel.allowsMultipleSelection = false
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.allowedFileTypes = ["png", "jpg", "jpeg"]

if panel.runModal() == .OK {
    if let url = panel.url {
        print("用户选择的文件路径:\(url.path)")
    }
}

常用属性

1、canChooseFiles:是否可以选择文件,true 表示可以。

panel.canChooseFiles = true

2、canChooseDirectories:是否可以选择目录,true 表示可以。

panel.canChooseDirectories = true

如果为false,则在目录视图中无法点击“打开”按钮。

3、allowsMultipleSelection:是否允许多选,true 可选多个文件或目录。

panel.allowsMultipleSelection = true

为true时,则无法按住Shift或拖动鼠标选择区域多选文件或目录。

4、urls:当用户允许多选(allowsMultipleSelection = true)时,这个数组包含所有选中的文件或目录。

for file in panel.urls {
    print(file.path)
}

5、allowedFileTypes:限制选择的文件类型,[“pdf”, “txt”]。

panel.allowedFileTypes = ["pdf", "txt"]

6、directoryURL:默认打开的文件夹,FileManager.default.homeDirectoryForCurrentUser。

panel.directoryURL = FileManager.default.homeDirectoryForCurrentUser

7、title:弹窗标题,”打开文件”。

panel.title = "打开文件"

在大多数现代 macOS 系统(尤其是 macOS 11 Big Sur 及以后)中,这个标题不会在 UI 上真正显示出来。这是 Apple 系统 UI 改动的结果。

8、message:窗口上方提示文字,”请选择一个文档”。

panel.message = "请选择一个文档"

9、resolvesAliases:是否自动解析 Finder 中的“别名”文件(.alias 文件)。默认是 true。

panel.resolvesAliases = true

通常不需要改动,保持默认即可。

10、canResolveUbiquitousConflicts(macOS 10.10+):是否允许处理 iCloud 文件的版本冲突(iCloud 文件夹中可能有多个版本)。

用于打开 iCloud Drive 文件时,自动解决冲突。

panel.canResolveUbiquitousConflicts = true

11、canDownloadUbiquitousContents(macOS 10.10+):如果文件在 iCloud 中但未下载,是否允许自动下载该文件。

默认是 true,适用于从 iCloud 打开文件时。

panel.canDownloadUbiquitousContents = true

12、isAccessoryViewDisclosed(macOS 10.11+):如果设置了 accessoryView(自定义底部 UI),是否展开显示它。

默认是 false,可以设置为 true 显示。

panel.isAccessoryViewDisclosed = true

13、prompt:修改确认按钮文字(如“打开” 改成 “导入”)。

panel.prompt = "导入"

14、showsHiddenFiles:是否显示隐藏文件(.开头的文件)。

panel.showsHiddenFiles = true

15、treatsFilePackagesAsDirectories:.app 等包是否视为文件夹。

panel.treatsFilePackagesAsDirectories = true

16、accessoryView:自定义底部视图,例如格式选项。

在 NSOpenPanel 或 NSSavePanel 底部添加一个 popup 按钮,供用户选择文件格式。

let panel = NSSavePanel()

// 1. 创建 accessoryView(自定义视图)
let formatPopup = NSPopUpButton(frame: NSRect(x: 0, y: 0, width: 200, height: 26))
formatPopup.addItems(withTitles: ["PNG", "JPEG", "TIFF"])
panel.accessoryView = formatPopup
panel.isAccessoryViewDisclosed = true // 默认展开

// 2. 其他常规设置
panel.title = "导出图片"
panel.nameFieldStringValue = "image.png"
panel.allowedFileTypes = ["png"]

// 3. 弹出面板
if panel.runModal() == .OK, let url = panel.url {
    let selectedFormat = formatPopup.titleOfSelectedItem
    print("保存到: \(url.path)")
    print("用户选择的格式: \(selectedFormat ?? "")")
}

总结

NSOpenPanel可以实现用户选择某个文件夹或图片、文件,支持批量导入。

当NSOpenPanel获取文件路径后,就可以直接访问文件,并且具备访问权限。

1、非沙盒(非 App Store)应用:获得路径后,可以自由读取、写入该路径下的文件。

2、沙盒(App Store 或启用 App Sandbox)应用:

仍然可以访问用户选中的文件,因为 NSOpenPanel 是用户授权访问的官方方式。

应用会获得的 URL 会携带一个“安全范围访问权限(security-scoped bookmark)”,可以用它来在后续使用中访问文件。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注