Swift iOS - 如何在两个 UIWindows 之间切换/切换并使其中一个成为 keyWindow

Swift iOS -How to Switch / Toggle between two UIWindows and make either the keyWindow

我创建了一个额外的 UIWindow,它将显示在主 window 之上。用户按下一个按钮,它就会过渡到主window。用户可以最小化额外的 window ,它将位于 tabBar 上方,如下图所示。他们可以将其放大以覆盖主要 window 或将其关闭并销毁。它工作正常。

我还创建了一个从屏幕底部启动的自定义操作 sheet。如果附加 window 完全覆盖主 window 并且启动动作 sheet,它将在附加 window 内完美启动。如果附加 window 不在屏幕上,它会在主 window 内完美启动。

问题是如果额外的 window 在屏幕上被最小化并且我想从主 window 启动操作 sheet,操作 sheet 在附加 window 内启动,它无法区分两者。 我打开 3D 可视化工具,它显示主要 window 是 off 和额外的 window 是 on.

在显示自定义操作 sheet 时如何区分两者 windows?

顺便说一句,如果两个 windows 都存在并且动作 sheet 是从主 window 启动的,我隐藏附加的 window。我还查看了其他答案,他们说使用 UIApplication.shared.keyWindow.addSubview 我已经在做。

CustomActionSheet Class:

var collectionView: UICollectionView!
var deltaY: CGFloat!
let height: CGFloat = 200 // 4 cells x 50 pts each

func displayActionSheet(){

     if let window = UIApplication.shared.keyWindow {

         // collectionView initialized...
         window.addSubview(collectionView)

         deltaY = window.frame.height - height

         collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)

         UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.curveEaseOut], animations: {

             self.collectionView.frame = CGRect(x: 0, y: deltaY, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
         }
      }
}

主视图Class:

@IBAction func mainWindowActionSheetButton(_ sender: UIButton) {

      let customActionSheet = CustomActionSheet()
      customActionSheet.displayActionSheet()
}

附加窗口Class:

let myVC = MyController()
var nav: UINavigationController?
var window: UIWindow!
var maximized = true

override init() {
    super.init()

    window = UIWindow()
    window.backgroundColor = .clear
    window.windowLevel = UIWindowLevelStatusBar
    nav = UINavigationController(rootViewController: myVC)
    window.rootViewController = nav
    window?.isHidden = false
    window?.makeKeyAndVisible()
 }

 func maximizeOrMinimizeWindow() {

    if maximized {
         // show this full screen
    } else {
        // show this window minimized like in the picture
    }
 }

另一个控制器 Class 具有同时启动操作的按钮 sheet:

@IBAction func additionalWindowActionSheetButton(_ sender: UIButton) {

      let customActionSheet = CustomActionSheet()
      customActionSheet.displayActionSheet()
}

在评论中总结建议。

问题是操作 sheet 总是从 key window 显示,但额外的 window 仍然是 key window 即使最小化。

显而易见的解决方案是在最小化附加项时将主 window 设为键 window。参见 UIWindow.makeKey() or UIWindow.makeKeyAndVisible()

由于 UIApplication.shared.windows 按 window 级别排序(后面的第一个),您始终可以使用 UIApplication.shared.windows.first.

到达主要的 window

因此

UIApplication.shared.windows.first?.makeKey()

将使主 window 成为 window 并且最小化的 window 将不再是 window.

这是@Sulthan 接受的答案的代码分解。阅读代码中的注释以获得解释。

let myVC = MyController()
var nav: UINavigationController?
var window: UIWindow!
var maximized = true

override init() {
    super.init()

    window = UIWindow()
    window.backgroundColor = .clear
    window.windowLevel = UIWindowLevelStatusBar
    nav = UINavigationController(rootViewController: myVC)
    window.rootViewController = nav!
    window?.isHidden = false
     // window?.makeKeyAndVisible() // don't call this because it doesn't need to be the keyWindow as of yet. The window?.isHidden property above this makes the window visible
 }

 func maximizeOrMinimizeWindow() {

    if maximized {

        window.first?.makeKey // when the additional window is maximized make it the keyWindow
    } else {

        UIApplication.shared.windows.first?.makeKey() // when the additional window is minimized set the main window back as the key window
    }
 }

还应该说明,当附加 window 从超级视图中删除或销毁时,确保使用 UIApplication.shared.windows.first?.makeKey()[=12 将主 window 设置回 keyWindow =]