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

如何为SwiftUI macOS应用添加可创建多实例窗口的File菜单项?

在SwiftUI macOS应用中实现多实例功能窗口及自定义菜单项

核心思路

要实现多实例窗口,必须用WindowGroup而非Window——Window是单实例结构体,而WindowGroup天生支持创建多个独立窗口实例。我们给每个功能(Wordle、Anagrams、Crosswords)分别定义专属的WindowGroup,再通过自定义菜单项触发打开对应窗口组的新实例。

具体实现步骤

1. 定义多实例窗口组

在你的App结构体中,针对macOS平台单独声明每个功能的WindowGroup,iOS平台保留原有的TabView结构:

@main
struct WordPuzzleApp: App {
    var body: some Scene {
        #if os(macOS)
        // Wordle多实例窗口组
        WindowGroup(id: "wordle-window") {
            WordleView()
                .frame(minWidth: 400, minHeight: 600)
        }
        .windowStyle(.titleBar)
        
        // Anagrams多实例窗口组
        WindowGroup(id: "anagrams-window") {
            AnagramsView()
                .frame(minWidth: 400, minHeight: 600)
        }
        .windowStyle(.titleBar)
        
        // Crosswords多实例窗口组
        WindowGroup(id: "crosswords-window") {
            CrosswordsView()
                .frame(minWidth: 600, minHeight: 800)
        }
        .windowStyle(.titleBar)
        #else
        // iOS平台保留TabView单实例结构
        WindowGroup {
            TabView {
                WordleView()
                    .tabItem { Label("Wordle", systemImage: "square.grid.2x2") }
                AnagramsView()
                    .tabItem { Label("Anagrams", systemImage: "textformat") }
                CrosswordsView()
                    .tabItem { Label("Crosswords", systemImage: "square.and.pencil") }
            }
        }
        #endif
    }
}

2. 添加自定义File菜单项

在App结构体中添加commands修饰符,给macOS平台的File菜单新增三个自定义选项,每个选项通过openWindow(id:)触发对应窗口组的新实例:

@main
struct WordPuzzleApp: App {
    var body: some Scene {
        // 上面的WindowGroup/TabView代码...
        
        #if os(macOS)
        CommandGroup(after: .newItem) {
            Button("New Wordle Window") {
                openWindow(id: "wordle-window")
            }
            .keyboardShortcut("W", modifiers: [.command, .shift])
            
            Button("New Anagrams Window") {
                openWindow(id: "anagrams-window")
            }
            .keyboardShortcut("A", modifiers: [.command, .shift])
            
            Button("New Crosswords Window") {
                openWindow(id: "crosswords-window")
            }
            .keyboardShortcut("C", modifiers: [.command, .shift])
        }
        #endif
    }
}

关键细节说明

  • WindowGroup的id是核心标识:调用openWindow(id:)时,系统会根据这个ID找到对应的窗口组,并创建一个全新的实例。
  • 自定义快捷键:给每个菜单项添加快捷键可以提升用户体验,比如Cmd+Shift+W对应Wordle窗口,贴合macOS操作习惯。
  • 窗口样式与尺寸:可以给每个WindowGroup设置windowStyle和初始尺寸,让不同功能的窗口更贴合需求。

验证效果

运行macOS应用后,打开File菜单就能看到新增的三个选项,每次点击都会弹出对应功能的全新窗口,所有窗口独立运行、互不干扰;iOS平台则保持原有的TabView切换逻辑。

内容的提问来源于stack exchange,提问作者Duncan C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:00:00