如何在visionOS的SwiftUI中以编程方式关闭指定标识的窗口?
关闭Vision Pro中指定标识的自定义窗口
首先,确保你的MyData结构体遵循Codable和Hashable协议——这是WindowGroup标识类型的必备要求:
struct MyData: Codable, Hashable { let intValue: Int let stringValue: String }
对应的WindowGroup定义示例:
@main struct MyVisionProApp: App { var body: some Scene { WindowGroup(for: MyData.self) { $data in MyCustomView(data: data) } // 其他窗口组... } }
要编程关闭这类窗口,核心思路是通过UIApplication获取所有场景会话,过滤出关联MyData标识的会话后销毁,具体实现如下:
关闭所有MyData标识的窗口
import UIKit func closeAllMyDataWindows() { guard let app = UIApplication.shared as? UIApplication else { return } // 筛选出所有带MyData标识的窗口场景会话 let targetSessions = app.connectedScenes .compactMap { $0 as? UIWindowScene } .map { $0.session } .filter { session in guard let userActivity = session.userActivity, let data = userActivity.userInfo?[NSUserActivityTypeKey] as? Data else { return false } // 尝试解码验证是否为MyData类型 return (try? JSONDecoder().decode(MyData.self, from: data)) != nil } // 逐个销毁会话(对应关闭窗口) targetSessions.forEach { app.requestSceneSessionDestruction($0, options: nil) } }
关闭特定匹配的MyData窗口
如果需要精准关闭某一个(或某一批)符合条件的窗口,只需修改过滤逻辑:
func closeTargetMyDataWindow(targetInt: Int, targetString: String) { guard let app = UIApplication.shared as? UIApplication else { return } let targetSessions = app.connectedScenes .compactMap { $0 as? UIWindowScene } .map { $0.session } .filter { session in guard let userActivity = session.userActivity, let data = userActivity.userInfo?[NSUserActivityTypeKey] as? Data, let myData = try? JSONDecoder().decode(MyData.self, from: data) else { return false } // 匹配目标参数 return myData.intValue == targetInt && myData.stringValue == targetString } targetSessions.forEach { app.requestSceneSessionDestruction($0, options: nil) } }
注意事项
requestSceneSessionDestruction是异步操作,窗口不会立即关闭- 调用方法时需确保应用处于活跃状态,场景会话已加载
- 若自定义了WindowGroup的userActivity类型,需调整
NSUserActivityTypeKey对应的键值
内容的提问来源于stack exchange,提问作者János
相关产品推荐
相关产品推荐

