Macos NSAlert:使第二个按钮同时成为默认按钮和取消按钮

Macos NSAlert:使第二个按钮同时成为默认按钮和取消按钮,macos,cocoa,nsalert,Macos,Cocoa,Nsalert,苹果最初的HIGs(现在不幸地从网站上消失了)声明: 对话框中最右边的按钮“操作”按钮是确认警报消息文本的按钮。操作按钮通常是默认按钮,但并不总是 在我的例子中,我有一些破坏性操作(如擦除磁盘)需要“安全”确认对话框,如下所示: 最糟糕的选择是创建一个对话框,其中最右边的按钮将变成“请勿擦除”按钮,而左边的按钮(通常是取消按钮)将变成“擦除”按钮,因为这很容易导致灾难(微软制作的对话框只有一次),因为人们被训练在想要取消操作时点击第二个按钮 所以,我需要的是,左(取消)按钮成为默认按钮,并对R

苹果最初的HIGs(现在不幸地从网站上消失了)声明:

对话框中最右边的按钮“操作”按钮是确认警报消息文本的按钮。操作按钮通常是默认按钮,但并不总是

在我的例子中,我有一些破坏性操作(如擦除磁盘)需要“安全”确认对话框,如下所示:

最糟糕的选择是创建一个对话框,其中最右边的按钮将变成“请勿擦除”按钮,而左边的按钮(通常是取消按钮)将变成“擦除”按钮,因为这很容易导致灾难(微软制作的对话框只有一次),因为人们被训练在想要取消操作时点击第二个按钮

所以,我需要的是,左(取消)按钮成为默认按钮,并对Return、Esc和cmd period键做出反应

要使其成为默认值并对返回键作出反应,我只需将第一个按钮的
keyEquivalent
设置为空字符串,将第二个按钮设置为“\r”


但是如何在Esc或cmd-时取消警报。键入了吗?

按照通常的方式设置NSALRT,并指定默认按钮。创建一个具有空边界的NSView的新子类,并将其添加为NSAlert的附件视图。在子类的
performkeyeequivalent
中,检查Esc是否与call
[-NSApplication stopModalWithCode:][/code>或
[-NSWindow endSheet:returnCode:][/code>匹配

#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);
}

一个按钮对两个按钮都有反应,这肯定是对HIG不利的↩ 及⎋. 无论如何,不能为按钮指定两个不同的等效键。您可以设计一个自定义视图并实现自己的逻辑来处理鼠标和键盘事件。如果您的取消按钮实际标题为“取消”?@vadian我不同意。你能给macOS看一篇支持你主张的HIG文章吗?@KenThomases是的,我忘了提到它不是“取消”,而是“不要删除”或类似的东西。我意识到将其命名为Cancel可能是一个简单的解决方案。在macOS Catalina上,“保存”对话框的“文件替换确认”警报默认设置为“取消”按钮。此外,macOS指南还指出,我在这里的ObjC中发布了一个代码示例:-请将其复制到您的答案中,然后我很高兴完全接受它;也可以随意改进。很高兴我能提供帮助,并感谢示例代码。:)