macOS SwiftUI应用:如何设置窗口不可关闭并禁用对应功能?
macOS SwiftUI 实现窗口不可关闭的方案
目前SwiftUI原生没有提供完全脱离NSWindow底层的方式实现这两个需求,还是需要借助AppKit的NSWindow相关API完成,以下是具体实现方案:
1. 禁用窗口左上角的红色关闭按钮
直接修改窗口的样式掩码,移除关闭按钮的样式:
struct UnclosableView: View { var body: some View { Text("无法关闭的窗口") .frame(width: 300, height: 200) .onAppear { // 获取当前窗口并移除关闭按钮样式 NSApplication.shared.windows.last?.styleMask.remove(.closeButton) } } }
2. 禁用「文件->关闭」菜单命令(仅针对该窗口)
通过NSWindowRepresentable包装窗口,并实现代理方法阻止关闭操作、禁用对应菜单:
struct UnclosableWindow: NSWindowRepresentable { func makeNSWindow(context: Context) -> NSWindow { let window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 300, height: 200), styleMask: [.titled, .miniaturizable, .resizable], // 不包含.closeButton backing: .buffered, defer: false ) window.contentViewController = NSHostingController(rootView: UnclosableContent()) window.delegate = context.coordinator return window } func updateNSWindow(_ window: NSWindow, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator() } class Coordinator: NSObject, NSWindowDelegate { // 阻止窗口关闭请求 func windowShouldClose(_ sender: NSWindow) -> Bool { return false } // 验证菜单有效性,禁用关闭命令 override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { if menuItem.action == #selector(NSWindow.performClose(_:)) { return false } return super.validateMenuItem(menuItem) } } } struct UnclosableContent: View { var body: some View { Text("不可关闭窗口的内容") .padding() } }
以上方案可同时满足两个需求:既隐藏了关闭按钮,又禁用了对应的菜单命令,且仅作用于目标窗口。
内容的提问来源于stack exchange,提问作者Grant Neufeld
相关产品推荐
相关产品推荐

