SwiftUI iOS应用中能否将WindowGroup与DocumentGroup结合使用?
解决方案
实现思路:不需要将DocumentGroup设置为应用入口,仅需在App的场景声明中同时注册原有WindowGroup和带唯一标识的DocumentGroup,之后在WindowGroup的视图中通过系统环境变量调起即可,完整保留DocumentGroup的所有原生特性。
步骤1:定义自定义文档模型
首先创建遵循FileDocument(动态文档可使用ReferenceFileDocument)的自定义文档类型,示例代码:
import SwiftUI import UniformTypeIdentifiers struct CustomDocument: FileDocument { // 替换为你自己的文档UTType static var readableContentTypes: [UTType] { [.init(filenameExtension: "mydoc")!] } var content: String = "" init(configuration: ReadConfiguration) throws { if let data = configuration.file.regularFileContents, let string = String(data: data, encoding: .utf8) { content = string } } init(initialContent: String = "") { self.content = initialContent } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let data = content.data(using: .utf8)! return .init(regularFileWithContents: data) } }
提前在项目Info配置中补充对应文档类型的UTI声明,确保系统可识别你的文档格式。
步骤2:在App中同时注册两个场景
在主App结构体中同时声明入口WindowGroup和带唯一ID的DocumentGroup:
@main struct DemoApp: App { var body: some Scene { // 保留原有WindowGroup作为入口 WindowGroup { MainView() } // 注册DocumentGroup,添加唯一ID用于后续调用 DocumentGroup(newDocument: CustomDocument()) { file in // 替换为你自己的文档编辑视图 DocumentEditView(document: file.$document) } .id("CustomDocumentScene") } }
步骤3:在WindowGroup的视图中调起DocumentGroup
在需要触发打开文档场景的视图中,调用openWindow环境值即可:
struct MainView: View { @Environment(\.openWindow) private var openWindow var body: some View { Button("新建文档") { // 新建空白文档直接调用对应ID的场景即可 openWindow(id: "CustomDocumentScene") } } }
效果验证
调起的DocumentGroup会完整保留所有原生特性:包括自带的文档浏览器、自动iCloud同步、文件重命名/移动/分享、版本回退等功能,和直接将DocumentGroup设为入口的文档类应用表现完全一致。
注意事项
- 该方案最低支持iOS 16+/macOS 13+,对应SwiftUI 4及以上版本
- 若需要打开指定路径的已有文档,直接在
openWindow的value参数传入对应文档实例或URL即可
内容的提问来源于stack exchange,提问作者Heyman
相关产品推荐
相关产品推荐

