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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:59:02