Swift iOS-如何在两个UIWindows之间切换/切换并设置keyWindow

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

我创建了一个附加的UIWindow,它将显示在主窗口的顶部。用户按下一个按钮,它将在主窗口上切换。用户可以最小化附加窗口,它会像下面的图片一样位于tabBar上方。他们可以将其放大以覆盖主窗口,也可以将其关闭并销毁。它工作正常。

我还创建了一个自定义操作表,该操作表从屏幕底部启动。如果附加窗口完全覆盖了主窗口并启动了操作表,则它将在附加窗口内完美启动。如果屏幕上没有其他窗口,它将在主窗口内完美启动。

问题是,如果屏幕上最小化了其他窗口,而我想从主窗口启动操作表,则该操作表将在其他窗口内启动,因此无法区分这两个窗口。我打开了3D可视化器,它显示主窗口为off,附加窗口为on

显示自定义操作表时如何区分两个窗口?

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

CustomActionSheet类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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)
         }
      }
}

MainView类别:

1
2
3
4
5
@IBAction func mainWindowActionSheetButton(_ sender: UIButton) {

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

AdditionalWindow类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
    }
 }

AnotherController类,该类具有也可启动操作表的按钮:

1
2
3
4
5
@IBAction func additionalWindowActionSheetButton(_ sender: UIButton) {

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

window in window

main window

additional window


在注释中总结建议。

问题在于操作表总是从关键窗口显示,但是附加窗口即使最小化也仍然是关键窗口。

显而易见的解决方案是在最小化附加窗口时将主窗口设置为关键窗口。 请参见UIWindow.makeKey()或UIWindow.makeKeyAndVisible()。

由于UIApplication.shared.windows是按窗口级别排序的(后一个优先),因此您始终可以使用UIApplication.shared.windows.first到达主窗口。

因此

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

将使主窗口成为关键窗口,而最小化窗口将不再是关键窗口。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
    }
 }

还应说明,当其他窗口从超级视图中删除或销毁时,请确保使用UIApplication.shared.windows.first?.makeKey()将主窗口重新设置为keyWindow。