如何通过按ESC键关闭窗口(NSWindowController)? [英] How to close window (NSWindowController) by hitting the ESC key?

查看:479
本文介绍了如何通过按ESC键关闭窗口(NSWindowController)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望用户可以通过按ESC键来关闭窗口,但是在这种特定情况下我无法使其工作,按ESC会触发错误声音(不,您不能那样做" macOS bloop),什么也没发生.

I would like the user being able to close a window by hitting the ESC key but I can't get it to work in this specific case, hitting ESC triggers an error sound (the "no you can't do that" macOS bloop) and nothing happens.

我正在制作NSWindowController的子类,它本身创建了NSViewController的子类的实例并将其设置在视图中.两个控制器都有自己的xib文件.

I'm making a subclass of NSWindowController which itself creates an instance of a subclass of NSViewController and sets it in a view. Both controllers have their own xib file.

NSWindowController:

NSWindowController:

final class MyWindowController: NSWindowController, NSWindowDelegate {

    @IBOutlet weak var targetView: MainView!

    let myVC: MyViewController!
    var params: SomeParams!

    override func windowDidLoad() {
        super.windowDidLoad()
        myVC = MyViewController(someParams: params)
        myVC.view.setFrameSize(targetView.frame.size)
        myVC.view.setBoundsSize(targetView.bounds.size)
        targetView.addSubview(myVC.view)
    }

    override var windowNibName: String! {
        return "MyWindowController"
    }

    convenience init(someParams params: SomeType) {
        self.init(window: nil)
        self.params = params
    }

}

NSViewController:

NSViewController:

final class MyViewController: NSViewController {

    convenience init(someParams params: SomeType) {
        // do stuff with the params
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // configure stuff for the window
    }

}

我尝试过的

假设,我的问题是当我希望targetView(一个NSTableView)的内容成为第一响应者时,MyWindowController NSWindow是.initialFirstResponder-这样我就可以我猜想使用keyDown,然后从此处将关闭命令发送到窗口.不过,这似乎并不是最佳选择.

What I've tried

I suppose that my issue is that the MyWindowController NSWindow is the .initialFirstResponder when I would want the content of the targetView (an NSTableView) to be the first responder - this way I could use keyDown, I guess, and send the close command to the window from there. This doesn't seem optimal, though.

我已经尝试通过在MyWindowController的windowDidLoad中使用window?.makeFirstResponder(theView)强制视图控制器视图成为第一响应者,但是没有任何变化.

I've tried forcing the view controller views into being the first responder by using window?.makeFirstResponder(theView) in the windowDidLoad of MyWindowController but nothing ever changes.

我还尝试将其添加到MyWindowController中:

I've also tried adding this to MyWindowController:

override func cancelOperation(_ sender: Any?) {
    print("yeah, let's close!")
}

但这仅在用户单击窗口背景然后按ESC时有效,并且仍然发出错误声音.实际上,这就是让我认为问题出在第一响应者在窗户上的原因.

But this only works if the user clicks first on the background of the window then hits ESC, and it still emits the error sound anyway. Which is actually what made me think that the issue was about the first responder being on the window.

您将如何实现?当然,我知道用户已经可以使用CMD + W关闭窗口,但是我还是很想解决这个问题.

How would you achieve that? Of course, I know that the user can already close the window with CMD+W, but I'd really like to sort out this issue nonetheless.

请注意,代码示例在Swift中,但是我也可以使用Objective-C接受解释.

推荐答案

cancelOperation的文档解释了cancelOperation应该如何工作:

The documentation of cancelOperation explains how cancelOperation should work:

此方法绑定到Escape和Command-. (句号)键.密钥窗口首先在视图层次结构中搜索一个等效于输入的Escape或Command-.的视图.如果这些视图中的任何一个都不能处理等效键,则该窗口将默认操作消息cancelOperation:发送给第一个响应者,然后该消息沿响应者链向上传播.

This method is bound to the Escape and Command-. (period) keys. The key window first searches the view hierarchy for a view whose key equivalent is Escape or Command-., whichever was entered. If none of these views handles the key equivalent, the window sends a default action message of cancelOperation: to the first responder and from there the message travels up the responder chain.

如果响应者链中没有响应者实现cancelOperation:,则键窗口在视图层次结构中搜索键等效项为Escape的视图(请注意,如果原始键等效项为Escape,则这可能是多余的).如果找不到这样的响应者,则会将cancel:操作消息发送到实现它的响应者链中的第一个响应者.

If no responder in the responder chain implements cancelOperation:, the key window searches the view hierarchy for a view whose key equivalent is Escape (note that this may be redundant if the original key equivalent was Escape). If no such responder is found, then a cancel: action message is sent to the first responder in the responder chain that implements it.

NSResponder声明但未实现此方法.

NSResponder declares but does not implement this method.

NSWindow实现cancelOperation:,并且不检查下一个响应程序(窗口控制器)是否实现cancelOperation:. cancel:消息确实到达窗口控制器.实施

NSWindow implements cancelOperation: and the next responder, the window controller, isn't checked for an implementation of cancelOperation:. The cancel: message does arrive at the window controller. Implementing

- (void)cancel:(id)sender
{
    NSLog(@"cancel");
}

将起作用. cancel:消息不是从超类继承的,因此自动完成功能不建议它.

will work. The cancel: message isn't inherited from a superclass so autocompletion doesn't suggest it.

这篇关于如何通过按ESC键关闭窗口(NSWindowController)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆