在连接多个场景时,获取当前UIScene时出现问题。
具体地说,我的应用程序(iOS 13)在iPad上支持多窗口。当我有两个并排的窗口,并且我访问连接场景的应用程序(使用UIApplication.shared.connectedScenes)时,所有这些应用程序的activationState都设置为.foregroundActive。但我实际上只和其中的一个互动。
我在stackoverflow上找到了一些代码来检索当前的key窗口(不记得是谁发布的),但正如你所看到的,它总是返回两个窗口中的一个。
let keyWindow: UIWindow? = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first我是否遗漏了一些方法来确定与之交互的最后一个窗口,或者多个.foregroundActive状态是错误的吗?
谢谢!
发布于 2019-08-29 17:37:03
我通过重构代码找到了问题的解决方案,现在我可以通过任何视图或视图控制器的window属性访问当前的UIScene窗口。这样我就不再需要keyWindow了。
我认为两个相邻打开的窗口都有activationState .foregroundActive,这可能是正确的
如果有人需要它,这是两个扩展,帮助我从应用程序中的任何地方访问当前窗口:
extension UIViewController {
var window: UIWindow? {
return view.window
}
}
extension UIScene {
var window: UIWindow? {
return (delegate as? SceneDelegate)?.window
}
}但如果你不能访问UIView、UIViewController或UIScene,这个问题仍然存在。例如在不引用视图或场景的数据模型内。然后,我看不到一种方法来一致地访问用户正在交互的正确窗口。
发布于 2021-03-29 21:50:17
虽然苹果在iOS 13.0之后不再推荐使用UIApplication.shared.keyWindow,但这个属性似乎可以帮助你在前景中有多个场景时找到活动的一个,方法是使用:
UIApplication.shared.keyWindow?.windowScene发布于 2019-11-14 18:11:00
我在我的项目中使用了这个扩展
// 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
}
}然后我可以这样做,当我必须展示一些东西的时候:
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()
}
}使用它,我几乎可以从任何地方获得一个窗口。但问题是,如果我根本无法访问与视图相关的对象,这是不可能的。例如,在我的身份验证服务中,我必须使用这个废话:
func authorize() {
if #available(iOS 13.0, *) {
guard let currentWindowScene = UIApplication.firstWindowScene else { return }
presenter.present(in: currentWindowScene)
} else {
presenter.present()
}
}对于我来说,这看起来不正确,而且它只适用于第一个windowScene。最好不要像我一样这样做,你必须详细说明这个解决方案。
https://stackoverflow.com/questions/57679284
复制相似问题