首页 > 其他分享 >Mac开发基础26-NSOpenPanel和NSSavePanel

Mac开发基础26-NSOpenPanel和NSSavePanel

时间:2024-08-06 18:28:57浏览次数:6  
标签:26 completionHandler url openPanel Mac allowedFileTypes savePanel NSSavePanel NS

NSOpenPanelNSSavePanel 是 macOS 应用中的两个重要控件,分别用于文件和文件夹的选择(打开)以及文件的保存(保存)。

NSOpenPanel

NSOpenPanel 是用于展示系统的打开文件对话框的类,用户可以通过它来选择文件或文件夹。

基本使用

Objective-C

#import <Cocoa/Cocoa.h>

// 创建并配置 NSOpenPanel
NSOpenPanel *openPanel = [NSOpenPanel openPanel];

// 允许用户选择文件
[openPanel setCanChooseFiles:YES];

// 允许用户选择文件夹
[openPanel setCanChooseDirectories:YES];

// 允许多选
[openPanel setAllowsMultipleSelection:YES];

// 设置对话框标题
[openPanel setTitle:@"选择文件或文件夹"];

// 显示对话框,并异步处理用户选择
[openPanel beginWithCompletionHandler:^(NSModalResponse result) {
    if (result == NSModalResponseOK) {
        // 获取用户选择的 URL 列表
        NSArray<NSURL *> *urls = [openPanel URLs];
        for (NSURL *url in urls) {
            NSLog(@"选择的文件/文件夹: %@", url.path);
        }
    } else {
        NSLog(@"用户取消了选择");
    }
}];

Swift

import Cocoa

// 创建并配置 NSOpenPanel
let openPanel = NSOpenPanel()

// 允许用户选择文件
openPanel.canChooseFiles = true

// 允许用户选择文件夹
openPanel.canChooseDirectories = true

// 允许多选
openPanel.allowsMultipleSelection = true

// 设置对话框标题
openPanel.title = "选择文件或文件夹"

// 显示对话框,并异步处理用户选择
openPanel.begin { result in
    if result == .OK {
        // 获取用户选择的 URL 列表
        let urls = openPanel.urls
        for url in urls {
            print("选择的文件/文件夹: \(url.path)")
        }
    } else {
        print("用户取消了选择")
    }
}

配置文件类型过滤

Objective-C

// 只允许选择特定类型的文件(例如:只选择图片文件)
[openPanel setAllowedFileTypes:@[@"jpg", @"png", @"gif"]];

Swift

// 只允许选择特定类型的文件(例如:只选择图片文件)
openPanel.allowedFileTypes = ["jpg", "png", "gif"]

指定初始目录

Objective-C

// 设置初始目录
[openPanel setDirectoryURL:[NSURL fileURLWithPath:@"/Users/username/Documents"]];

Swift

// 设置初始目录
openPanel.directoryURL = URL(fileURLWithPath: "/Users/username/Documents")

处理用户取消操作

Objective-C

[openPanel beginWithCompletionHandler:^(NSModalResponse result) {
    if (result == NSModalResponseOK) {
        // 用户选择了文件或文件夹
    } else {
        // 用户取消了操作
        NSLog(@"用户取消了选择");
    }
}];

Swift

openPanel.begin { result in
    if result == .OK {
        // 用户选择了文件或文件夹
    } else {
        // 用户取消了操作
        print("用户取消了选择")
    }
}

NSSavePanel

NSSavePanel 是用于展示系统的保存文件对话框的类,用户可以通过它来选择保存文件的位置和名称。

基本使用

Objective-C

#import <Cocoa/Cocoa.h>

// 创建并配置 NSSavePanel
NSSavePanel *savePanel = [NSSavePanel savePanel];

// 设置对话框标题
[savePanel setTitle:@"保存文件"];

// 设置默认文件名
[savePanel setNameFieldStringValue:@"Untitled.txt"];

// 显示对话框,并异步处理用户选择
[savePanel beginWithCompletionHandler:^(NSModalResponse result) {
    if (result == NSModalResponseOK) {
        NSURL *saveURL = [savePanel URL];
        NSLog(@"保存路径: %@", saveURL.path);
        
        // 在这里可以进行文件保存操作,例如将数据写入到 saveURL 所指示的文件路径中
    } else {
        NSLog(@"用户取消了保存");
    }
}];

Swift

import Cocoa

// 创建并配置 NSSavePanel
let savePanel = NSSavePanel()

// 设置对话框标题
savePanel.title = "保存文件"

// 设置默认文件名
savePanel.nameFieldStringValue = "Untitled.txt"

// 显示对话框,并异步处理用户选择
savePanel.begin { result in
    if result == .OK {
        if let saveURL = savePanel.url {
            print("保存路径: \(saveURL.path)")
            
            // 在这里可以进行文件保存操作,例如将数据写入到 saveURL 所指示的文件路径中
        }
    } else {
        print("用户取消了保存")
    }
}

配置文件类型限制

Objective-C

// 只允许保存特定类型的文件(例如:只保存为文本文件)
[savePanel setAllowedFileTypes:@[@"txt"]];

Swift

// 只允许保存特定类型的文件(例如:只保存为文本文件)
savePanel.allowedFileTypes = ["txt"]

指定初始目录和文件名

Objective-C

// 设置初始目录
[savePanel setDirectoryURL:[NSURL fileURLWithPath:@"/Users/username/Documents"]];

// 设置默认文件名
[savePanel setNameFieldStringValue:@"MyDocument.txt"];

Swift

// 设置初始目录
savePanel.directoryURL = URL(fileURLWithPath: "/Users/username/Documents")

// 设置默认文件名
savePanel.nameFieldStringValue = "MyDocument.txt"

强制文件扩展名

Objective-C

// 强制附加的文件扩展名
[savePanel setExtensionHidden:NO];

Swift

// 强制附加的文件扩展名
savePanel.isExtensionHidden = false

封装工具类

为了更方便地使用 NSOpenPanelNSSavePanel,可以封装一个工具类,提供常见功能的高层接口。

Objective-C

#import <Cocoa/Cocoa.h>

@interface FileDialogHelper : NSObject

+ (void)showOpenPanelWithTitle:(NSString *)title
               canChooseFiles:(BOOL)canChooseFiles
          canChooseDirectories:(BOOL)canChooseDirectories
        allowsMultipleSelection:(BOOL)allowsMultipleSelection
               allowedFileTypes:(NSArray<NSString *> *)allowedFileTypes
              completionHandler:(void (^)(NSArray<NSURL *> *urls))completionHandler;

+ (void)showSavePanelWithTitle:(NSString *)title
               defaultFileName:(NSString *)defaultFileName
               allowedFileTypes:(NSArray<NSString *> *)allowedFileTypes
              completionHandler:(void (^)(NSURL *url))completionHandler;

@end

@implementation FileDialogHelper

+ (void)showOpenPanelWithTitle:(NSString *)title
               canChooseFiles:(BOOL)canChooseFiles
          canChooseDirectories:(BOOL)canChooseDirectories
        allowsMultipleSelection:(BOOL)allowsMultipleSelection
               allowedFileTypes:(NSArray<NSString *> *)allowedFileTypes
              completionHandler:(void (^)(NSArray<NSURL *> *urls))completionHandler {
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel setTitle:title];
    [openPanel setCanChooseFiles:canChooseFiles];
    [openPanel setCanChooseDirectories:canChooseDirectories];
    [openPanel setAllowsMultipleSelection:allowsMultipleSelection];
    [openPanel setAllowedFileTypes:allowedFileTypes];
    
    [openPanel beginWithCompletionHandler:^(NSModalResponse result) {
        if (result == NSModalResponseOK) {
            completionHandler([openPanel URLs]);
        } else {
            completionHandler(nil);
        }
    }];
}

+ (void)showSavePanelWithTitle:(NSString *)title
               defaultFileName:(NSString *)defaultFileName
               allowedFileTypes:(NSArray<NSString *> *)allowedFileTypes
              completionHandler:(void (^)(NSURL *url))completionHandler {
    NSSavePanel *savePanel = [NSSavePanel savePanel];
    [savePanel setTitle:title];
    [savePanel setNameFieldStringValue:defaultFileName];
    [savePanel setAllowedFileTypes:allowedFileTypes];
    
    [savePanel beginWithCompletionHandler:^(NSModalResponse result) {
        if (result == NSModalResponseOK) {
            completionHandler([savePanel URL]);
        } else {
            completionHandler(nil);
        }
    }];
}

@end

Swift

import Cocoa

class FileDialogHelper {
    
    // 显示打开对话框
    static func showOpenPanel(title: String,
                              canChooseFiles: Bool,
                              canChooseDirectories: Bool,
                              allowsMultipleSelection: Bool,
                              allowedFileTypes: [String]?,
                              completionHandler: @escaping ([URL]?) -> Void) {
        let openPanel = NSOpenPanel()
        openPanel.title = title
        openPanel.canChooseFiles = canChooseFiles
        openPanel.canChooseDirectories = canChooseDirectories
        openPanel.allowsMultipleSelection = allowsMultipleSelection
        openPanel.allowedFileTypes = allowedFileTypes
        
        openPanel.begin { result in
            if result == .OK {
                completionHandler(openPanel.urls)
            } else {
                completionHandler(nil)
            }
        }
    }
    
    // 显示保存对话框
    static func showSavePanel(title: String,
                              defaultFileName: String,
                              allowedFileTypes: [String]?,
                              completionHandler: @escaping (URL?) -> Void) {
        let savePanel = NSSavePanel()
        savePanel.title = title
        savePanel.nameFieldStringValue = defaultFileName
        savePanel.allowedFileTypes = allowedFileTypes
        
        savePanel.begin { result in
            if result == .OK {
                completionHandler(savePanel.url)
            } else {
                completionHandler(nil)
            }
        }
    }
}

使用示例

Objective-C

// 使用示例:显示打开对话框
[FileDialogHelper showOpenPanelWithTitle:@"选择文件或文件夹"
                          canChooseFiles:YES
                     canChooseDirectories:YES
                   allowsMultipleSelection:YES
                          allowedFileTypes:@[@"jpg", @"png"]
                         completionHandler:^(NSArray<NSURL *> *urls) {
    if (urls) {
        for (NSURL *url in urls) {
            NSLog(@"选择的文件/文件夹: %@", url.path);
        }
    } else {
        NSLog(@"用户取消了选择");
    }
}];

// 使用示例:显示保存对话框
[FileDialogHelper showSavePanelWithTitle:@"保存文件"
                          defaultFileName:@"Untitled.txt"
                          allowedFileTypes:@[@"txt"]
                         completionHandler:^(NSURL *url) {
    if (url) {
        NSLog(@"保存路径: %@", url.path);
    } else {
        NSLog(@"用户取消了保存");
    }
}];

Swift

// 使用示例:显示打开对话框
FileDialogHelper.showOpenPanel(title: "选择文件或文件夹",
                               canChooseFiles: true,
                               canChooseDirectories: true,
                               allowsMultipleSelection: true,
                               allowedFileTypes: ["jpg", "png"]) { urls in
    if let urls = urls {
        for url in urls {
            print("选择的文件/文件夹: \(url.path)")
        }
    } else {
        print("用户取消了选择")
    }
}

// 使用示例:显示保存对话框
FileDialogHelper.showSavePanel(title: "保存文件",
                               defaultFileName: "Untitled.txt",
                               allowedFileTypes: ["txt"]) { url in
    if let url = url {
        print("保存路径: \(url.path)")
    } else {
        print("用户取消了保存")
    }
}

深入探讨

自定义面板行为

有时候,你可能希望自定义 NSOpenPanelNSSavePanel 的行为,例如在用户选择某个文件或目录时执行特定的检查。

Objective-C

// Example of custom delegate for NSOpenPanel
@interface CustomOpenPanelDelegate : NSObject <NSOpenPanelDelegate>
@end

@implementation CustomOpenPanelDelegate

- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
    // 只允许选择特定的文件或目录
    if ([url.pathExtension isEqualToString:@"txt"]) {
        return YES;
    }
    return NO;
}

@end

// 使用自定义代理
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
CustomOpenPanelDelegate *delegate = [[CustomOpenPanelDelegate alloc] init];
[openPanel setDelegate:delegate];

Swift

// Example of custom delegate for NSOpenPanel
class CustomOpenPanelDelegate: NSObject, NSOpenPanelDelegate {
    func panel(_ sender: Any, shouldEnable url: URL) -> Bool {
        // 只允许选择特定的文件或目录
        if url.pathExtension == "txt" {
            return true
        }
        return false
    }
}

// 使用自定义代理
let openPanel = NSOpenPanel()
let delegate = CustomOpenPanelDelegate()
openPanel.delegate = delegate

面板定制界面

你可以在 NSOpenPanelNSSavePanel 中添加额外的用户界面元素,例如文本字段或复选框。

Objective-C

NSOpenPanel *openPanel = [NSOpenPanel openPanel];

// 创建自定义视图,例如一个 NSTextField
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[textField setStringValue:@"请输入额外信息"];

// 添加自定义视图到面板
[openPanel setAccessoryView:textField];

Swift

let openPanel = NSOpenPanel()

// 创建自定义视图,例如一个 NSTextField
let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 24))
textField.stringValue = "请输入额外信息"

// 添加自定义视图到面板
openPanel.accessoryView = textField

总结

通过了解 NSOpenPanelNSSavePanel 的基本使用、配置文件类型和初始目录、处理用户操作、自定义面板行为以及添加自定义界面等技巧,并封装工具类,将能够更高效地使用这两个类创建和管理文件选择和保存对话框。

标签:26,completionHandler,url,openPanel,Mac,allowedFileTypes,savePanel,NSSavePanel,NS
From: https://www.cnblogs.com/chglog/p/18345782

相关文章

  • 设计师的超强素材管理神器,支持多级打标签,支持Win/Mac双系统
    作为一名设计师,整理和管理各种素材是我们日常花费比较多时间的工作流之一。但是当我们收集的素材积累到一定量后,整理和查找素材将会非常麻烦。这么多零散的素材内容,积累到一起的结果就是,每次想要找一个素材,就需要花费一定的时间在电脑上到处寻找。 为了解决这个问题,千鹿设计......
  • Mac开发基础24-NSToolbar
    NSToolbar是macOS应用中的一个重要控件,用于创建窗口顶部的工具栏。工具栏通常包含按钮和其他控件,用户可以通过这些控件快速访问常用功能。NSToolbar和NSToolbarItem协同工作,NSToolbar是工具栏容器,而NSToolbarItem是工具栏项。下面我们详细介绍NSToolbar的常见API和基......
  • Mac开发基础25-NSAlert
    NSAlert是macOS应用中的一个重要控件,用于显示警告与通知对话框。NSAlert允许开发者创建和配置弹出窗口,用于通知用户、确认操作或显示错误信息。基本使用创建和显示简单的警告框Objective-C#import<Cocoa/Cocoa.h>//实例化NSAlertNSAlert*alert=[[NSAlertalloc]......
  • Mac开发基础22-NSTabView
    NSTabView是macOS应用中的一个重要控件,用于创建带有多个选项卡的界面,类似于网页浏览器的选项卡功能。它能够将多个视图容器合并到一个控件中,每个视图容器都可以通过选项卡来切换。基本使用创建和初始化Objective-C#import<Cocoa/Cocoa.h>//创建一个NSTabView实例NST......
  • Mac开发基础23-NSMenu
    NSMenu是macOS应用中的一个重要控件,用于创建应用程序的菜单。这些菜单通常出现在屏幕顶部的菜单栏中,但也可以作为上下文菜单出现。NSMenu和NSMenuItem协同工作,NSMenu是菜单容器,而NSMenuItem是菜单项。本指南将详细介绍NSMenu的常见API和基础技巧。基本使用创建和初......
  • Mac开发基础21-NSSplitView
    NSSplitView是macOS应用中的一个重要控件,允许用户调整窗口中的各个子视图大小。它通常用于创建可调整大小的面板布局,例如侧边栏和主内容区域。在本指南中,我们将详细介绍NSSplitView的常见API和基础技巧,并深入探讨相关知识。基本使用创建和初始化Objective-C#import<Co......
  • Mac开发基础20-NSCollectionView
    NSCollectionView是macOS开发中的一种强大控件,类似于iOS上的UICollectionView,用于展示和管理网格、列表等多种布局的数据展示视图。1.基本使用创建和初始化Objective-C#import<Cocoa/Cocoa.h>//创建并初始化一个NSCollectionView实例NSCollectionView*collecti......
  • Mac开发基础19-NSTableView(二)
    进阶使用和技巧1.单击和双击行事件处理Objective-C//单击行时的处理-(void)tableView:(NSTableView*)tableViewdidClickTableColumn:(NSTableColumn*)tableColumn{NSIntegerclickedRow=[tableViewclickedRow];if(clickedRow>=0){NSLog(@"Si......
  • Mac开发基础18-NSTableView(一)
    NSTableView是macOS应用程序中用于显示和管理数据表格的控件。它提供了丰富的API和高度自定义的能力,使得开发者可以精细地控制表格的显示和行为。本文将详细介绍NSTableView的常见API和一些基础技巧,并深入探讨其相关知识。1.基本使用创建和初始化Objective-C#import......
  • LlamaCoder:一款开源的平替 Claude Artifacts 项目
    LlamaCoder是一个开源项目,旨在提供一种替代ClaudeArtifacts的解决方案。ClaudeArtifacts是一个商业软件,可能包含一些专有技术或特定的功能集,而LlamaCoder则致力于提供类似的功能,但以开源的形式,允许更广泛的社区参与和贡献。由于LlamaCoder是一个假想的开源项目,我将......