我正在尝试编写https://stackoverflow.com/a/74935849/2178159的 macOS 版本。
据我了解,我应该能够设置menu
一个属性NSResponder
,它会在右键单击时自动显示。
我尝试过几件事:
A:设置menu
在 上NSHostingController
-view
当我执行此操作并右键单击或按住 Ctrl 键单击时,什么也没有发生。B:直接设置menu
在 上NSHostingController
- 当我执行此操作时,会出现崩溃Abstract method -[NSResponder setMenu:] called from class _TtGC7SwiftUI19NSHostingControllerGVS_21_ViewModifier_...__. Subclasses must override
C:手动调用或 的自NSMenu.popup
定义子类的方法 - 什么也没有发生。NSHostingController
NSView
rightMouseDown
extension View {
func contextMenu(menu: NSMenu) -> some View {
modifier(ContextMenuViewModifier(menu: menu))
}
}
struct ContextMenuViewModifier: ViewModifier {
let menu: NSMenu
func body(content: Content) -> some View {
Interaction_UI(
view: { content },
menu: menu
)
.fixedSize()
}
}
private struct Interaction_UI<Content: View>: NSViewRepresentable {
typealias NSViewType = NSView
@ViewBuilder var view: Content
let menu: NSMenu
func makeNSView(context: Context) -> NSView {
let v = NSHostingController(rootView: view)
// option A - no effect
v.view.menu = menu
// option B - crash
v.menu = menu
return v.view
}
func updateNSView(_ nsView: NSViewType, context: Context) {
// part of option A
nsView.menu = menu
}
}
的视图类
NSHostingController
可能已重写menu(for:)
或设置了属性,或者在设置后menu
可能已将其设置menu
为其他内容(例如,为了实现 SwiftUI )。毕竟,与 UIKit 中将上下文菜单添加到数组不同,只有一个属性可以设置。.contextMenu { ... }
interactions
menu
NSView
我建议进行子类化
NSHostingView
和覆盖menu(for:)
以返回您自己的NSMenu
属性。然后
NSViewRepresentable
可以这样写:这是一个右键单击时产生菜单的最小示例:
实际上,您可能会将 放在可以响应菜单项操作的/
NSMenu
中。该类也可以是菜单的。@Observable
ObservableObject
delegate