Mac開發基礎25-NSAlert

Mr.陳發表於2024-08-06

NSAlert 是 macOS 應用中的一個重要控制元件,用於顯示警告與通知對話方塊。NSAlert 允許開發者建立和配置彈出視窗,用於通知使用者、確認操作或顯示錯誤資訊。

基本使用

建立和顯示簡單的警告框

Objective-C

#import <Cocoa/Cocoa.h>

// 例項化 NSAlert
NSAlert *alert = [[NSAlert alloc] init];

// 設定警告標題
[alert setMessageText:@"警告"];

// 設定詳細資訊
[alert setInformativeText:@"這是一個警告對話方塊"];

// 新增按鈕
[alert addButtonWithTitle:@"確定"];
[alert addButtonWithTitle:@"取消"];

// 顯示同步模式對話方塊 (阻塞,等待使用者響應)
NSModalResponse response = [alert runModal];
if (response == NSAlertFirstButtonReturn) {
    NSLog(@"使用者點選了確定");
} else if (response == NSAlertSecondButtonReturn) {
    NSLog(@"使用者點選了取消");
}

Swift

import Cocoa

// 例項化 NSAlert
let alert = NSAlert()

// 設定警告標題
alert.messageText = "警告"

// 設定詳細資訊
alert.informativeText = "這是一個警告對話方塊"

// 新增按鈕
alert.addButton(withTitle: "確定")
alert.addButton(withTitle: "取消")

// 顯示同步模式對話方塊 (阻塞,等待使用者響應)
let response = alert.runModal()
if response == .alertFirstButtonReturn {
    print("使用者點選了確定")
} else if response == .alertSecondButtonReturn {
    print("使用者點選了取消")
}

配置警告型別和樣式

Objective-C

// 設定警告型別 (例如:NSAlertStyleWarning,NSAlertStyleInformational,NSAlertStyleCritical)
[alert setAlertStyle:NSAlertStyleWarning];

Swift

// 設定警告型別 (例如:.warning,.informational,.critical)
alert.alertStyle = .warning

顯示非同步模式對話方塊

Objective-C

// 顯示非同步模式對話方塊,使用 completionHandler 來處理使用者響應
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
    if (returnCode == NSAlertFirstButtonReturn) {
        NSLog(@"使用者點選了確定");
    } else if (returnCode == NSAlertSecondButtonReturn) {
        NSLog(@"使用者點選了取消");
    }
}];

Swift

// 顯示非同步模式對話方塊,使用 completionHandler 來處理使用者響應
alert.beginSheetModal(for: self.window!) { response in
    if response == .alertFirstButtonReturn {
        print("使用者點選了確定")
    } else if response == .alertSecondButtonReturn {
        print("使用者點選了取消")
    }
}

高階用法

為警告對話方塊新增自定義檢視

Objective-C

// 建立一個自定義檢視 (例如,包含一個 NSTextField)
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[textField setStringValue:@"請輸入你的名字"];

// 新增自定義檢視到警告對話方塊
[alert setAccessoryView:textField];

Swift

// 建立一個自定義檢視 (例如,包含一個 NSTextField)
let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 24))
textField.stringValue = "請輸入你的名字"

// 新增自定義檢視到警告對話方塊
alert.accessoryView = textField

禁用按鈕的自動佈局

預設情況下,NSAlert 會為按鈕設定自動佈局。對於更復雜的佈局,可以禁用自動佈局。

Objective-C

// 禁用按鈕的自動佈局
[alert setShowsSuppressionButton:YES];
[alert.suppressionButton setTitle:@"不再顯示此訊息"];

Swift

// 禁用按鈕的自動佈局
alert.showsSuppressionButton = true
alert.suppressionButton?.title = "不再顯示此訊息"

響應抑制按鈕點選

NSAlert 可以包含一個抑制按鈕(Suppression Button),用於抑制將來的顯示。

Objective-C

// 在 completionHandler 中處理抑制按鈕點選
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
    if ([alert suppressionButton].state == NSControlStateValueOn) {
        NSLog(@"使用者選擇不再顯示此訊息");
    }
}];

Swift

// 在 completionHandler 中處理抑制按鈕點選
alert.beginSheetModal(for: self.window!) { response in
    if alert.suppressionButton?.state == .on {
        print("使用者選擇不再顯示此訊息")
    }
}

建立不同樣式的警告對話方塊

Objective-C

// 設定對話方塊為資訊提示樣式
[alert setAlertStyle:NSAlertStyleInformational];

// 設定對話方塊為警告樣式
[alert setAlertStyle:NSAlertStyleWarning];

// 設定對話方塊為嚴重錯誤樣式
[alert setAlertStyle:NSAlertStyleCritical];

Swift

// 設定對話方塊為資訊提示樣式
alert.alertStyle = .informational

// 設定對話方塊為警告樣式
alert.alertStyle = .warning

// 設定對話方塊為嚴重錯誤樣式
alert.alertStyle = .critical

封裝工具類

為了更方便地使用 NSAlert,可以封裝一個工具類,提供常見功能的高層介面。

Objective-C

#import <Cocoa/Cocoa.h>

@interface NSAlertHelper : NSObject

+ (void)showAlertWithTitle:(NSString *)title message:(NSString *)message inWindow:(NSWindow *)window;
+ (void)showCustomAlertWithTitle:(NSString *)title message:(NSString *)message accessoryView:(NSView *)accessoryView inWindow:(NSWindow *)window;
+ (void)showAsyncAlertWithTitle:(NSString *)title message:(NSString *)message inWindow:(NSWindow *)window completionHandler:(void (^)(NSModalResponse))completionHandler;

@end

@implementation NSAlertHelper

+ (void)showAlertWithTitle:(NSString *)title message:(NSString *)message inWindow:(NSWindow *)window {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setMessageText:title];
    [alert setInformativeText:message];
    [alert addButtonWithTitle:@"確定"];
    [alert addButtonWithTitle:@"取消"];
    [alert beginSheetModalForWindow:window completionHandler:nil];
}

+ (void)showCustomAlertWithTitle:(NSString *)title message:(NSString *)message accessoryView:(NSView *)accessoryView inWindow:(NSWindow *)window {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setMessageText:title];
    [alert setInformativeText:message];
    [alert addButtonWithTitle:@"確定"];
    [alert addButtonWithTitle:@"取消"];
    [alert setAccessoryView:accessoryView];
    [alert beginSheetModalForWindow:window completionHandler:nil];
}

+ (void)showAsyncAlertWithTitle:(NSString *)title message:(NSString *)message inWindow:(NSWindow *)window completionHandler:(void (^)(NSModalResponse))completionHandler {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setMessageText:title];
    [alert setInformativeText:message];
    [alert addButtonWithTitle:@"確定"];
    [alert addButtonWithTitle:@"取消"];
    [alert beginSheetModalForWindow:window completionHandler:completionHandler];
}

@end

Swift

import Cocoa

class NSAlertHelper {
    
    // 顯示簡單的警告對話方塊
    static func showAlert(title: String, message: String, inWindow window: NSWindow) {
        let alert = NSAlert()
        alert.messageText = title
        alert.informativeText = message
        alert.addButton(withTitle: "確定")
        alert.addButton(withTitle: "取消")
        alert.beginSheetModal(for: window, completionHandler: nil)
    }
    
    // 顯示帶有自定義檢視的警告對話方塊
    static func showCustomAlert(title: String, message: String, accessoryView: NSView, inWindow window: NSWindow) {
        let alert = NSAlert()
        alert.messageText = title
        alert.informativeText = message
        alert.accessoryView = accessoryView
        alert.addButton(withTitle: "確定")
        alert.addButton(withTitle: "取消")
        alert.beginSheetModal(for: window, completionHandler: nil)
    }
    
    // 顯示非同步警告對話方塊
    static func showAsyncAlert(title: String, message: String, inWindow window: NSWindow, completionHandler: @escaping (NSApplication.ModalResponse) -> Void) {
        let alert = NSAlert()
        alert.messageText = title
        alert.informativeText = message
        alert.addButton(withTitle: "確定")
        alert.addButton(withTitle: "取消")
        alert.beginSheetModal(for: window, completionHandler: completionHandler)
    }
}

使用示例

Objective-C

// 使用示例:顯示簡單的警告對話方塊
[NSAlertHelper showAlertWithTitle:@"警告" message:@"這是一個警告對話方塊" inWindow:self.window];

// 使用示例:顯示帶有自定義檢視的警告對話方塊
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[textField setStringValue:@"請輸入你的名字"];
[NSAlertHelper showCustomAlertWithTitle:@"輸入" message:@"請輸入資訊" accessoryView:textField inWindow:self.window];

// 使用示例:顯示非同步警告對話方塊
[NSAlertHelper showAsyncAlertWithTitle:@"非同步警告" message:@"這是一個非同步警告對話方塊" inWindow:self.window completionHandler:^(NSModalResponse returnCode) {
    if (returnCode == NSAlertFirstButtonReturn) {
        NSLog(@"使用者點選了確定");
    } else if (returnCode == NSAlertSecondButtonReturn) {
        NSLog(@"使用者點選了取消");
    }
}];

Swift

// 使用示例:顯示簡單的警告對話方塊
NSAlertHelper.showAlert(title: "警告", message: "這是一個警告對話方塊", inWindow: self.window!)

// 使用示例:顯示帶有自定義檢視的警告對話方塊
let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 24))
textField.stringValue = "請輸入你的名字"
NSAlertHelper.showCustomAlert(title: "輸入", message: "請輸入資訊", accessoryView: textField, inWindow: self.window!)

// 使用示例:顯示非同步警告對話方塊
NSAlertHelper.showAsyncAlert(title: "非同步警告", message: "這是一個非同步警告對話方塊", inWindow: self.window!) { response in
    if response == .alertFirstButtonReturn {
        print("使用者點選了確定")
    } else if response == .alertSecondButtonReturn {
        print("使用者點選了取消")
    }
}

總結

透過了解 NSAlert 的基本使用、配置警告型別和樣式、顯示非同步模式對話方塊、新增自定義檢視、響應抑制按鈕點選以及建立不同樣式的警告對話方塊等高階用法,並封裝工具類,你將能夠更高效地使用 NSAlert 建立複雜的提示系統。在實際應用中,合理使用這些技巧可以顯著提升使用者介面的靈活性和使用者體驗。

相關文章