簡體   English   中英

如何獲取多窗口 SceneDelegate Xcode 11 的當前鍵窗口等效項?

[英]How get current keywindow equivalent for multi window SceneDelegate Xcode 11?

我正在將適用於 iPadOS 的 iOS13 應用程序轉換為 SceneDelegate(多窗口)。

如何從當前的 SceneDelegate 獲取當前的 UIWindow?

我知道 a 可以使用UIView.windowUIViewController.view.window訪問當前場景,但我有一個非 UI 類(AppDelegate),我需要在其中獲取窗口(直到 iOS12 的 keyWindow)以在頂部顯示小吃店一切。

我曾經做過[UIApplication sharedApplication].keyWindow但現在,當然,這是錯誤的。

斯威夫特 5.x / iOS 13.x

受到許多解決方案的啟發,為了找回我的舊窗口屬性(在 connectedScenes 中搜索它),我實現了一個小擴展:

extension UIApplication {
    var currentWindow: UIWindow? {
        connectedScenes
        .filter({$0.activationState == .foregroundActive})
        .map({$0 as? UIWindowScene})
        .compactMap({$0})
        .first?.windows
        .filter({$0.isKeyWindow}).first
    }
}

用法

if let window = UIApplication.shared.currentWindow { 
   // do whatever you want with window
}

您需要簡單地遍歷所有窗口並手動查找關鍵窗口。

for (UIWindow *window in [UIApplication sharedApplication].windows) {
    if (window.isKeyWindow) {
        // you have the key window
        break;
    }
}

不要使用UISceneActivationStateForegroundActive作為檢查。 這意味着一些不同的東西,人們通過使用邏輯來找到第一個UISceneActivationStateForegroundActive窗口場景來引入錯誤。

聽起來您可能想將此邏輯移至您的 SceneDelegate。

SceneDelegate 現在知道窗口是否連接到場景,因此讓每個連接的場景監聽驅動小吃店的任何事件並將其顯示在其窗口上可能是有意義的。 這將導致每個可見窗口都顯示小吃店(1 個或更多)。

你可以試試:

    if let window = UIApplication.shared.windows.first(where: { (window) -> Bool in window.isKeyWindow}) {
    //your code
    }

希望這可以幫助!

現在您有多個窗口,每個場景一個。 首先,您必須回答您在使用時需要哪個。

可能您想獲取當前活動場景的窗口,然后您可以使用它:

    UIWindow* window = nil;
    if (@available(iOS 13.0, *))
    {
        for (UIWindowScene* wScene in [UIApplication sharedApplication].connectedScenes)
        {
            if (wScene.activationState == UISceneActivationStateForegroundActive)
            {
                window = wScene.windows.firstObject;

                break;
            }
        }
    }

對於SwiftUI ,在 iOS 16+ 中測試

extension UIApplication {
    var currentWindow: UIWindow? {
        connectedScenes
            .compactMap { $0 as? UIWindowScene }
            .first?
            .windows
            .first
    }
}

是用法。

guard let anchor = UIApplication.shared.currentWindow else {
   fatalError("Window did not found in Hierarchy")
}

我還沒有嘗試過,但是您應該能夠使用[UIApplication sharedApplication].windows獲取所有窗口,然后選擇是否要在所有窗口或一個窗口上顯示小吃欄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM