首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当多个连接的场景在前台处于活动状态时获取当前聚焦的UIScene

当多个连接的场景在前台处于活动状态时获取当前聚焦的UIScene
EN

Stack Overflow用户
提问于 2019-08-28 01:01:07
回答 4查看 2.6K关注 0票数 7

在连接多个场景时,获取当前UIScene时出现问题。

具体地说,我的应用程序(iOS 13)在iPad上支持多窗口。当我有两个并排的窗口,并且我访问连接场景的应用程序(使用UIApplication.shared.connectedScenes)时,所有这些应用程序的activationState都设置为.foregroundActive。但我实际上只和其中的一个互动。

我在stackoverflow上找到了一些代码来检索当前的key窗口(不记得是谁发布的),但正如你所看到的,它总是返回两个窗口中的一个。

代码语言:javascript
复制
let keyWindow: UIWindow? = UIApplication.shared.connectedScenes
    .filter({$0.activationState == .foregroundActive})
    .map({$0 as? UIWindowScene})
    .compactMap({$0})
    .first?.windows
    .filter({$0.isKeyWindow}).first

我是否遗漏了一些方法来确定与之交互的最后一个窗口,或者多个.foregroundActive状态是错误的吗?

谢谢!

EN

回答 4

Stack Overflow用户

发布于 2019-08-29 17:37:03

我通过重构代码找到了问题的解决方案,现在我可以通过任何视图或视图控制器的window属性访问当前的UIScene窗口。这样我就不再需要keyWindow了。

我认为两个相邻打开的窗口都有activationState .foregroundActive,这可能是正确的

如果有人需要它,这是两个扩展,帮助我从应用程序中的任何地方访问当前窗口:

代码语言:javascript
复制
extension UIViewController {
  var window: UIWindow? {
    return view.window
  }
}

extension UIScene {
  var window: UIWindow? {
    return (delegate as? SceneDelegate)?.window
  }
}

但如果你不能访问UIViewUIViewControllerUIScene,这个问题仍然存在。例如在不引用视图或场景的数据模型内。然后,我看不到一种方法来一致地访问用户正在交互的正确窗口。

票数 2
EN

Stack Overflow用户

发布于 2021-03-29 21:50:17

虽然苹果在iOS 13.0之后不再推荐使用UIApplication.shared.keyWindow,但这个属性似乎可以帮助你在前景中有多个场景时找到活动的一个,方法是使用:

代码语言:javascript
复制
UIApplication.shared.keyWindow?.windowScene
票数 2
EN

Stack Overflow用户

发布于 2019-11-14 18:11:00

我在我的项目中使用了这个扩展

代码语言:javascript
复制
// MARK: - Scene Delegate helpers

@available(iOS 13.0, *)
extension UIApplication {
    static var firstScene: UIScene? {
        UIApplication.shared.connectedScenes.first
    }

    static var firstSceneDelegate: SceneDelegate? {
        UIApplication.firstScene?.delegate as? SceneDelegate
    }

    static var firstWindowScene: UIWindowScene? {
        UIApplication.firstSceneDelegate?.windowScene
    }
}

// MARK: - Window Scene sugar

@available(iOS 13.0, *)
protocol WindowSceneDependable {
    var windowScene: UIWindowScene? { get }
    var window: UIWindow? { get }
}

@available(iOS 13.0, *)
extension WindowSceneDependable {
    var windowScene: UIWindowScene? {
        window?.windowScene
    }
}

@available(iOS 13.0, *)
extension UIScene: WindowSceneDependable { }

@available(iOS 13.0, *)
extension SceneDelegate: WindowSceneDependable { }

@available(iOS 13.0, *)
extension UIViewController: WindowSceneDependable { }

// MARK: - Window sugar

@available(iOS 13.0, *)
extension UIScene {
    var window: UIWindow? {
        (delegate as? SceneDelegate)?.window
    }
}

extension UIViewController {
    var window: UIWindow? {
        view.window
    }
}

然后我可以这样做,当我必须展示一些东西的时候:

代码语言:javascript
复制
func present(from navigation: UINavigationController) {
    self.navigation = navigation

    if #available(iOS 13.0, *) {
        guard let currentWindowScene = navigation.windowScene else { return }
        myPresenter.present(in: currentWindowScene)
    } else {
        myPresenter.present()
    }
}

使用它,我几乎可以从任何地方获得一个窗口。但问题是,如果我根本无法访问与视图相关的对象,这是不可能的。例如,在我的身份验证服务中,我必须使用这个废话:

代码语言:javascript
复制
func authorize() {
    if #available(iOS 13.0, *) {
        guard let currentWindowScene = UIApplication.firstWindowScene else { return }
        presenter.present(in: currentWindowScene)
    } else {
        presenter.present()
    }
}

对于我来说,这看起来不正确,而且它只适用于第一个windowScene。最好不要像我一样这样做,你必须详细说明这个解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57679284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档