Skip to content

Commit

Permalink
fix: make getTopWindow more robust (#621)
Browse files Browse the repository at this point in the history
## 📜 Description

This PR updates the top window retrieval method:

Old: `UIApplication.shared.windows.last` (deprecated in iOS 15+)
New: `UIWindowScene`-based approach

Differences:

- `UIApplication.shared.windows.last`:
    - It accesses all windows associated with the application.
- The last window in this array isn't always the topmost or key window,
especially in more complex app setups.
- This approach is deprecated as of iOS 15, though it still works in
many cases.
- `UIWindowScene`:
- Iterates through all connected scenes to find the active foreground
scene
- Ensures selection of the correct key window in multi-window
environments (e.g., Split View in iPadOS)
- Provides more reliable behaviour in complex app configurations that
utilize multiple `UIWindowScenes`

## 💡 Motivation and Context

Closes #618

In our case, this change was required to get the children of the
`OverKeyboardView` to show. Without it, they were still rendered, but
invisible. This change should enhance the reliability across different
iOS versions and device types.

## 📢 Changelog

### iOS

- Get the last key window in the current `UIWindowScene` as opposed to
the last window of all windows associated with the app

## 🤔 How Has This Been Tested?

It works on my company project. Did not manage to get the example app to
compile on my machine. Could be due to the (lack of) provisioning
profiles.

## 📝 Checklist

- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
  • Loading branch information
thespacemanatee authored Oct 8, 2024
1 parent 0553cd8 commit a259792
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
16 changes: 16 additions & 0 deletions ios/extensions/UIApplication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ import Foundation
import UIKit

public extension UIApplication {
var activeWindow: UIWindow? {
if #available(iOS 13.0, *) {
for scene in connectedScenes {
if scene.activationState == .foregroundActive,
let windowScene = scene as? UIWindowScene,
let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow })
{
return keyWindow
}
}
return nil
} else {
return windows.last { $0.isKeyWindow }
}
}

static func topViewController(
base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController
) -> UIViewController? {
Expand Down
2 changes: 1 addition & 1 deletion ios/extensions/UIWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public extension UIWindow {

func getTopWindow() -> UIWindow? {
// Return the keyboard window if it's available, otherwise return the last window
return keyboardWindow ?? UIApplication.shared.windows.last
return keyboardWindow ?? UIApplication.shared.activeWindow
}
}

Expand Down

0 comments on commit a259792

Please sign in to comment.