【问题标题】:How do I add a view to the top of an app in iOS 13/14如何在 iOS 13/14 中将视图添加到应用程序的顶部
【发布时间】:2021-05-20 00:42:08
【问题描述】:

我正在尝试向我的应用程序添加一个视图,该视图在流中是持久的,并且位于所有其他视图之上。在以前的 iOS 版本中,我可以简单地向位于我的应用程序顶部的 UIWindow 添加一个子视图,但是从 iOS 13 开始,这似乎不再可能。

我尝试了以下方法,但没有成功: UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.addSubview(someView)

进一步调试,我的应用程序的视图层次结构中似乎根本没有窗口。我知道这一点,因为当在 follow forEach 语句上设置断点时,我从来没有得到要执行的断点。

UIApplication.shared.windows.forEach { (window) in
    window.addSubview(myView)
}

任何关于如何在所有 iOS 版本 11 到 14 上实现这一点的建议都将不胜感激。

【问题讨论】:

  • 你试过了吗? let window = UIApplication.shared.keyWindow! window.addSubview(myView)
  • @emrcftci 是的,尽管从 iOS 13 开始,该方法已被弃用

标签: ios swift uiview uiwindow


【解决方案1】:

您必须创建第二个UIWindow,分配rootViewController 并使其可见。

下面的代码是针对 SwiftUI 的,但是你可以用 UIKit 做同样的事情,只需创建一个窗口并设置window.isHidden = false

let secondWindow = UIWindow(windowScene: windowScene)
secondWindow.frame = CGRect(x: 0, y: 40, width: UIScreen.main.bounds.size.width, height: 100)
let someView = Text("I am on top of everything")
secondWindow.rootViewController = UIHostingController(rootView: someView)
secondWindow.isHidden = false

取决于您有多少个窗口。您可能需要更改第二个窗口的windowLevel。 您可以使用 Xcode 中的Debug View Hierarchy 检查窗口是否显示。

这是一个没有 SceneDelegate 的 UIKit 示例。如果您有场景委托,则必须将窗口场景传递给 UIWindow init。 不要忘记保留第二个窗口。


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    private enum Constants {
        static let sessionConfiguration = URLSessionConfiguration.default
    }

    var window: UIWindow?
    var secondWindow: UIWindow?

    // MARK: - UIApplicationDelegate

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {

        let window = UIWindow(frame: UIScreen.main.bounds)
        self.window = window
        let viewController = UIViewController()
        viewController.view.backgroundColor = .red

        window.rootViewController = viewController
        window.makeKeyAndVisible()

        let secondWindow = UIWindow()
        secondWindow.frame = CGRect(
            x: 0,
            y: 40,
            width: UIScreen.main.bounds.size.width,
            height: 100
        )

        let secondController = UIViewController()
        secondController.view.backgroundColor = .blue
        secondWindow.rootViewController = secondController
        secondWindow.isHidden = false
        self.secondWindow = secondWindow

        return true
    }
}

【讨论】:

  • 不幸的是,这不起作用。以下代码仅在我的应用程序之上呈现任何内容。 var window = UIWindow() window.frame = CGRect(x: 0, y: 0, width: 100, height: 100) window.rootViewController = UIViewController() window.addSubview(GridOverlayView()) window.isHidden = false
  • 我不确定你做错了什么,但我测试了 SceneDelegate 和没有,它都有效。
  • 所以这个实现的问题是它没有考虑到多个窗口。我会接受这一点并将其标记为已解决,但是对于在所有窗口中解决此问题的实现,您需要设置通知并观察新窗口何时可用。见github.com/bstillitano/Scyther
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
相关资源
最近更新 更多