SwiftUI 按钮到选择器操作

5
我需要让SwiftUI按钮在当前焦点组件上执行Objective-C选择器。以下方式可行:
let button = Button(action: {
  let command = #selector(NSStandardKeyBindingResponding.selectAll(_:))
   NSApplication.shared.currentEvent?.window?.firstResponder?.doCommand(by: command)
}, label: { Text("Select All") })

...但这显然非常丑陋。SwiftUI有一个Command结构体,可以包装一个Selector,但不清楚在创建命令后如何实际调用选择器。

当按下按钮时,发出任意Command的推荐方法是什么?

1个回答

1

如果您想沿着响应者链分派一个操作,可以使用-[NSApplication sendAction:to:from:]方法,并将目标设置为nil

如果您想要使用AppKit响应者链来处理操作,包括SwiftUI的NSHostingView和响应者链中的其他部分(其父视图、窗口等),则需要这样做。理论上,如果您想要处理来自SwiftUI内容的基于选择器的操作,可以使用onCommand修饰符来识别包装该选择器的Command。但是,您的NSHostingView需要在AppKit响应者链中,并且onCommand SwiftUI视图需要聚焦(或成为聚焦视图的祖先)才能识别命令。这样做的主要好处是,您还可以使用完全相同的代码处理菜单栏操作,因为菜单栏操作通常通过响应者链分派。

如果您正在尝试修改与其他SwiftUI视图相关的状态,将Binding或闭包参数作为参数传递给其初始化程序可能更直接。例如,您可以在其他地方维护一些状态(即“所选对象集”),然后将一个闭包传递给按钮以修改该状态(“将每个对象放入所选对象集中”),而无需直接教授按钮有关该状态的知识。


1
你有实际使用过这个吗?即使是像 MyFocsedView().onCommand(Command.copy) { print("copy!") } 这样的标准命令,至少在 beta3 中也无法实际执行。 - marcprux
我尝试了多种方法来测试onCommand(_:perform :)修饰符,但它没有被调用!如果能给出使用它的示例,我将不胜感激! :) - Vitya Shurapov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接