You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:44:54