NSAlert:使第二个按钮成为默认按钮和取消按钮
NSAlert: Make second button both the default and cancel button
Apple 最初的 HIG(遗憾的是现在从网站上消失了)声明:
对话框中最右边的按钮,操作按钮,是确认警报消息文本的按钮。操作按钮通常但不总是默认按钮
就我而言,我有一些破坏性操作(例如擦除磁盘)需要 "safe" 确认对话框,如下所示:
最糟糕的选择是制作一个对话框,其中最右边的按钮将变为 "do not erase" 按钮,而最左边的按钮(通常是取消按钮)将变为 "erase" 按钮,因为这很容易导致灾难(happened to me 使用一次 Microsoft 制作的对话框),因为人们受过训练,只要他们想取消操作就可以单击第二个按钮。
所以,我需要的是左(取消)按钮既成为默认按钮,又对 Return、Esc 和 cmd-period 键做出反应。
要使其成为默认值并响应 Return 键,我只需将第一个按钮的 keyEquivalent
设置为空字符串,将第二个按钮设置为“\r”。
但是如何在 Esc 或 cmd- 时也取消警报。打字了吗?
按照通常的方式设置 NSAlert,并分配默认按钮。创建一个具有空边界的 NSView 的新子类,并将其添加为 NSAlert 的附属视图。在子类的 performKeyEquivalent
中,检查 Esc 是否匹配调用 [-NSApplication stopModalWithCode:]
或 [-NSWindow endSheet:returnCode:]
.
#import "AppDelegate.h"
@interface AlertEscHandler : NSView
@end
@implementation AlertEscHandler
-(BOOL)performKeyEquivalent:(NSEvent *)event {
NSString *typed = event.charactersIgnoringModifiers;
NSEventModifierFlags mods = (event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask);
BOOL isCmdDown = (mods & NSEventModifierFlagCommand) != 0;
if ((mods == 0 && event.keyCode == 53) || (isCmdDown && [typed isEqualToString:@"."])) { // ESC key or cmd-.
[NSApp stopModalWithCode:1001]; // 1001 is the second button's response code
}
return [super performKeyEquivalent:event];
}
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self alertTest];
[NSApp terminate:0];
}
- (void)alertTest {
NSAlert *alert = [NSAlert new];
alert.messageText = @"alert msg";
[alert addButtonWithTitle:@"OK"];
NSButton *cancelButton = [alert addButtonWithTitle:@"Cancel"];
alert.window.defaultButtonCell = cancelButton.cell;
alert.accessoryView = [AlertEscHandler new];
NSModalResponse choice = [alert runModal];
NSLog (@"User chose button %d", (int)choice);
}
Apple 最初的 HIG(遗憾的是现在从网站上消失了)声明:
对话框中最右边的按钮,操作按钮,是确认警报消息文本的按钮。操作按钮通常但不总是默认按钮
就我而言,我有一些破坏性操作(例如擦除磁盘)需要 "safe" 确认对话框,如下所示:
最糟糕的选择是制作一个对话框,其中最右边的按钮将变为 "do not erase" 按钮,而最左边的按钮(通常是取消按钮)将变为 "erase" 按钮,因为这很容易导致灾难(happened to me 使用一次 Microsoft 制作的对话框),因为人们受过训练,只要他们想取消操作就可以单击第二个按钮。
所以,我需要的是左(取消)按钮既成为默认按钮,又对 Return、Esc 和 cmd-period 键做出反应。
要使其成为默认值并响应 Return 键,我只需将第一个按钮的 keyEquivalent
设置为空字符串,将第二个按钮设置为“\r”。
但是如何在 Esc 或 cmd- 时也取消警报。打字了吗?
按照通常的方式设置 NSAlert,并分配默认按钮。创建一个具有空边界的 NSView 的新子类,并将其添加为 NSAlert 的附属视图。在子类的 performKeyEquivalent
中,检查 Esc 是否匹配调用 [-NSApplication stopModalWithCode:]
或 [-NSWindow endSheet:returnCode:]
.
#import "AppDelegate.h"
@interface AlertEscHandler : NSView
@end
@implementation AlertEscHandler
-(BOOL)performKeyEquivalent:(NSEvent *)event {
NSString *typed = event.charactersIgnoringModifiers;
NSEventModifierFlags mods = (event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask);
BOOL isCmdDown = (mods & NSEventModifierFlagCommand) != 0;
if ((mods == 0 && event.keyCode == 53) || (isCmdDown && [typed isEqualToString:@"."])) { // ESC key or cmd-.
[NSApp stopModalWithCode:1001]; // 1001 is the second button's response code
}
return [super performKeyEquivalent:event];
}
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self alertTest];
[NSApp terminate:0];
}
- (void)alertTest {
NSAlert *alert = [NSAlert new];
alert.messageText = @"alert msg";
[alert addButtonWithTitle:@"OK"];
NSButton *cancelButton = [alert addButtonWithTitle:@"Cancel"];
alert.window.defaultButtonCell = cancelButton.cell;
alert.accessoryView = [AlertEscHandler new];
NSModalResponse choice = [alert runModal];
NSLog (@"User chose button %d", (int)choice);
}