【问题标题】:SwiftUI - How to use onCommand with NSMenuItem on macOSSwiftUI - 如何在 macOS 上使用 onCommand 和 NSMenuItem
【发布时间】:2019-09-22 12:08:45
【问题描述】:

我正在尝试找到在 macOS 上将 NSMenuItem 与 SwiftUI onCommand 连接的最佳解决方案。

目前我正在做以下事情:

  1. 在 AppDelegate 中,我创建了一个虚拟函数,以便能够列出函数 First Responder 收到的操作列表。
@IBAction func changeColor(_ sender: Any) {
    print("Dummy Function")
}
  1. 创建一个 NSMenuItem 并将其与 Main.storyboard 中的 First Responder 函数连接。

  2. 将所需的代码添加到我的 SwiftUI 视图中

struct TestView: View {

    let changeColor = #selector(AppDelegate.changeColor(_:))

    var body: some View {
        VStack {
            TextField("Text", text: .constant(""))
            Text("Hello World!")
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .onCommand(changeColor) {
            print("Change Color Action")
        }
    }
}

如果 TextField 是 First Responder,我会看到打印了“更改颜色操作”。 如果 TextField 之前不是 First Responder,则 View 不会成为 First Responder。也许这是目前 Catalina Beta (19A558d) 中的一个错误,因为我也无法集中精力工作。

【问题讨论】:

  • 您能否改写您的结尾段落以更清楚地描述问题?
  • 嘿,这与您的问题无关,但您是否使用 SwiftUI 构建了您的 NSMenu
  • 你有没有想过这个问题?我有类似的情况,很想知道你是否取得了任何进展。

标签: swift macos swiftui


【解决方案1】:

我已经能够通过首先创建视图 focusable 来实现此功能:

struct TestView: View {

    let changeColor = #selector(AppDelegate.changeColor(_:))

    var body: some View {
        VStack {
            TextField("Text", text: .constant(""))
            Text("Hello World!")
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .focusable() // Add this 
        .onCommand(changeColor) {
            print("Change Color Action")
        }
    }
}

那么您还必须选中“键盘系统偏好设置”中的“使用键盘导航在控件之间移动焦点”复选框

【讨论】:

  • 感谢您的回答。我知道首选项设置,但没有多少用户会打开此设置(我也是)。在正常的 macOS 开发中,您可以使任何自定义视图成为第一响应者,而无需打开此功能。我仍在寻找一个完全令人满意的解决方案。
  • 这似乎可以解决问题,但是onCommand 和那个设置之间有什么联系?
  • @Bill 在onCommand 的 SwiftUI 文档字符串中,它说“它包含的视图或其中一个视图必须处于焦点才能触发操作。...”.focusable() 和该设置必须允许吗?我仍然无法让它工作。
【解决方案2】:

我最终在我的 AppDelegate 中创建了一个 PassthroughSubject,将它传递给我的 SwiftUI 视图,并在我的 SwiftUI 视图拥有的模型对象中订阅它。当调用菜单命令的 AppDelegate 选择器时,我使用 PassthroughSubject 发送事件,我的模型会接收并适当地处理它。

我的回答绝对不理想,我很想知道您是否想出更好的方法来做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    相关资源
    最近更新 更多