aya*_*aio -1 macos cocoa first-responder nsviewcontroller nswindowcontroller
我希望用户可以通过按ESC键关闭一个窗口,但我不能让它在这种特定情况下工作,按ESC键会触发错误声音("你不能那样做"macOS bloop)没有任何反应.
我正在创建NSWindowController的子类,它本身创建一个NSViewController子类的实例并在视图中设置它.两个控制器都有自己的xib文件.
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
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
我想我的问题是MyWindowController NSWindow是.initialFirstResponder我希望targetView(一个NSTableView)的内容成为第一个响应者的时候 - keyDown我想这样我可以使用这种方式,并从那里发送关闭命令到窗口.但这似乎并不是最佳选择.
我已经尝试通过window?.makeFirstResponder(theView)在MyWindowController的windowDidLoad中使用强制视图控制器视图成为第一个响应者,但没有任何改变.
我也尝试将其添加到MyWindowController:
override func cancelOperation(_ sender: Any?) {
print("yeah, let's close!")
}
Run Code Online (Sandbox Code Playgroud)
但这仅在用户首先点击窗口背景然后点击ESC 时才有效,并且仍然会发出错误声音.这实际上是让我觉得这个问题是关于第一个响应者在窗口的问题.
你会如何实现这一目标?当然,我知道用户已经可以用CMD + W关闭窗口了,但是我真的很想解决这个问题.
请注意,代码示例在Swift中,但我也可以使用Objective-C接受解释.
文档cancelOperation解释了cancelOperation应该如何工作:
此方法绑定到Escape和Command-.(期间)钥匙.关键窗口首先在视图层次结构中搜索其等效键为Escape或Command-的视图,无论输入哪个.如果这些视图都不处理密钥等效项,则窗口向
cancelOperation:第一响应者发送默认操作消息,然后消息从响应者链向上传播.如果响应程序链中没有响应者实现
cancelOperation:,则关键窗口在视图层次结构中搜索其等效键为Escape的视图(请注意,如果原始密钥等效项为Escape,则这可能是多余的).如果没有找到这样的响应者,则将cancel:动作消息发送到实现它的响应者链中的第一响应者.
NSResponder声明但不实现此方法.
NSWindow实现cancelOperation:和下一个响应者,窗口控制器,没有检查实现cancelOperation:.该cancel:消息不会到达窗口控制器.实施
- (void)cancel:(id)sender
{
NSLog(@"cancel");
}
Run Code Online (Sandbox Code Playgroud)
将工作.该cancel:消息不是从超类继承的,因此自动完成不建议它.
这在 Xcode 10 和 Swift 4.2 中对我有用:
@objc func cancel(_ sender: Any?) {
close()
}
Run Code Online (Sandbox Code Playgroud)
我之前尝试过,但没有该@objc部分,它不起作用。所以不要省略它。
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |