Mac Catalyst技术问询:是否可将指定场景设置为激活状态?
解决Mac Catalyst多前台场景的激活问题
当然可行!你遇到的重复创建场景的问题,是因为调用requestSceneSessionActivation时没有指定已存在的目标场景会话,系统默认会创建新的场景副本。下面是具体的实现思路和代码示例:
核心思路
- 定位已存在的场景会话:遍历应用的所有打开场景会话(
openSessions),通过自定义标识找到目标场景的UISceneSession。 - 判断场景状态:确认目标会话处于前台状态(
foregroundActive或foregroundInactive,后者就是可见但非激活的状态)。 - 激活已有会话:调用
requestSceneSessionActivation时传入找到的会话,而不是传nil,系统就会将该场景切换为激活状态(最前端)。
代码实现示例
1. 为场景会话添加唯一标识(创建场景时)
首先要确保每个场景在创建时都有唯一的标识,方便后续查找。在AppDelegate或SceneDelegate的场景配置方法中添加:
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let config = UISceneConfiguration(name: "YourSceneConfigName", sessionRole: connectingSceneSession.role) // 这里用自定义ID标记场景,比如根据业务需求设置不同的标识 connectingSceneSession.userInfo["targetSceneID"] = "product-detail-scene" return config }
2. 激活已有前台场景的方法
实现一个工具方法,用来查找并激活目标场景:
func activateTargetScene(with sceneID: String) { // 遍历所有已打开的场景会话 guard let targetSession = UIApplication.shared.openSessions.first(where: { session in // 匹配自定义标识,同时确保场景处于前台状态(非后台) guard let sessionSceneID = session.userInfo?["targetSceneID"] as? String else { return false } return sessionSceneID == sceneID && session.state != .background }) else { // 如果目标场景不存在,再执行创建新场景的逻辑 createNewScene(with: sceneID) return } // 创建激活选项,可指定发起激活的场景(可选) let activationOptions = UIScene.ActivationRequestOptions() activationOptions.requestingScene = UIApplication.shared.connectedScenes.first as? UIWindowScene // 请求激活已存在的场景会话 UIApplication.shared.requestSceneSessionActivation( targetSession, userActivity: nil, options: activationOptions ) { error in if let error = error { print("激活场景失败:\(error.localizedDescription)") } } } // 创建新场景的辅助方法(原有的创建逻辑) private func createNewScene(with sceneID: String) { let config = UISceneConfiguration(name: "YourSceneConfigName", sessionRole: .windowApplication) // 给新会话设置标识 let newSession = UISceneSession(configuration: config) newSession.userInfo["targetSceneID"] = sceneID UIApplication.shared.requestSceneSessionActivation( newSession, userActivity: nil, options: nil ) { error in if let error = error { print("创建新场景失败:\(error.localizedDescription)") } } }
关键说明
- 场景状态区分:Mac Catalyst中,
UISceneSession.state的.foregroundInactive就是你说的“可见但非最前端”的状态,调用激活方法后会切换为.foregroundActive(最前端激活状态)。 - 避免重复创建:只要传入已存在的
UISceneSession实例,系统就不会创建新的场景副本,而是直接激活现有场景。 - 多窗口配置:确保你的应用已经开启多窗口支持——在Xcode项目设置的“Deployment Info”中勾选“Supports multiple windows”,或者在Info.plist的
UIApplicationSceneManifest下设置Enable Multiple Windows为YES。
内容的提问来源于stack exchange,提问作者BlueskyMed
相关产品推荐
相关产品推荐

