簡體   English   中英

如何獲取iOS 13中的狀態欄高度?

[英]How to get the status bar height in iOS 13?

在 iOS 13 UIApplication.shared.statusBarFrame.height警告

'statusBarFrame' 在 iOS 13.0 中被棄用:改為使用 window 場景的 statusBarManager 屬性。

如何在不使用 iOS 13 中已棄用的 API 的情況下獲取狀態欄高度?

作為警告提示,您可以訪問statusBarManager具有statusBarFrame屬性。 這是在UIWindowwindowScene上定義的。

let height = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

試試吧,我試過了。

let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first        
let height = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

解決方案:

這似乎在 iPhoneX+ 設備中也沒有任何警告地工作。

斯威夫特 4.2 / 5

if #available(iOS 13.0, *) {
    let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
    statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
} else {
    statusBarHeight = UIApplication.shared.statusBarFrame.height
}

嘗試一下。 希望能幫助到你。

我遇到了與 MMV 相同的問題(請參閱他們對 Jordan H 回答的評論), view.window?.windowScene?.statusBarManager?.statusBarFrame.height在我的應用程序啟動附近返回 nil。 特別是view.window返回 nil。 然后我嘗試在 UIApplication.shared 上搜索 windows 屬性:

for window in UIApplication.shared.windows

在我的情況下,這返回了兩個窗口。 兩個窗口具有相同的非零狀態欄高度。 我不確定為什么有兩個窗口,但至少兩個窗口都有相同的狀態欄高度。 我像這樣訪問狀態欄高度:

if let height = window.windowScene?.statusBarManager?.statusBarFrame.height

我決定在我的情況下,因為可能有不同的高度來為我的代碼取最大的高度。 這是我用於我的應用程序的代碼:

let statusBarHeight: CGFloat = {
    var heightToReturn: CGFloat = 0.0
         for window in UIApplication.shared.windows {
             if let height = window.windowScene?.statusBarManager?.statusBarFrame.height, height > heightToReturn {
                 heightToReturn = height
             }
         }
    return heightToReturn
}()

希望這可以幫助某人!

var statusBarHeight: CGFloat = 0
if #available(iOS 13.0, *) {
    statusBarHeight = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
} else {
    statusBarHeight = UIApplication.shared.statusBarFrame.height
}

獲取statusBarHeight的最新方法,如下:

    private lazy var statusBarHeight: CGFloat = {
        var statusBarHeight: CGFloat = 0
        if #available(iOS 13.0, *) {
            let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        } else {
            statusBarHeight = UIApplication.shared.statusBarFrame.height
        }
        return statusBarHeight
    }()

對於 Objective-C

我不確定 OC 中過濾器的替代品是什么,所以我使用 for 循環來獲取keyWindow 好吧,我在 iPhone 12 中得到的實際高度是“47”,而 iPhone 8 的實際高度是“20”。

    CGFloat statusBarHeight;
    if (@available(iOS 13, *)) {
        NSArray *windows = UIApplication.sharedApplication.windows;
        UIWindow *keyWindow = nil;
        
        for (UIWindow *window in windows) {
            if (window.isKeyWindow) {
                keyWindow = window;
                break;
            }
        }
        statusBarHeight = keyWindow.windowScene.statusBarManager.statusBarFrame.size.height;
        NSLog(@"statusBarHeight: %f", statusBarHeight);
    } else {
        statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height;
    }

對於 iOS 13:

在您的SceneDelegate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    let statusBarSize = windowScene.statusBarManager!.statusBarFrame
    ...// initialize your root view controller
 }
}

如果您想將該值傳遞給您的View ,您可以將該值設置為Environment並在您的View使用它。 例子:

首先我們需要創建我們的環境密鑰:

struct StatusBarSizeEnvironmentKey: EnvironmentKey {
   public static let defaultValue: CGRect = CGRect()
}

extension EnvironmentValues {
  public var statusBarSize: CGRect {
    set { self[StatusBarSizeEnvironmentKey.self] = newValue }
    get { self[StatusBarSizeEnvironmentKey] }
  }
}

並在SceneDelegate設置值:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    let statusBarSize = windowScene.statusBarManager!.statusBarFrame
    window.rootViewController = UIHostingController(rootView: YourView()
             .environment(\.statusBarSize, statusBarSize))
 }
}

從這里已經給出的很好的答案中學習,使用UIApplication connectScenes ,我們可以做一個擴展:

extension UIApplication {
    var statusBarHeight: CGFloat {
        connectedScenes
            .compactMap {
                $0 as? UIWindowScene
            }
            .compactMap {
                $0.statusBarManager
            }
            .map {
                $0.statusBarFrame
            }
            .map(\.height)
            .max() ?? 0
    }
}

用法:

let height = UIApplication.shared.statusBarHeight

從接受的答案中竊取:

guard let sbheight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height else {
     assertionFailure("usage error: VC lifecyclewise it becomes available no earlier than viewDidAppear")
}

UIApplication.shared.windowswindows在 iOS 15.0 中已棄用

iOS 15

 let statusBarHeight = UIApplication.shared.connectedScenes
        .filter {$0.activationState == .foregroundActive }
        .map {$0 as? UIWindowScene }
        .compactMap { $0 }
        .first?.windows
        .filter({ $0.isKeyWindow }).first?
        .windowScene?.statusBarManager?.statusBarFrame.height ?? 0

對於 Objective-C

- (CGFloat)statusBarHeight{
    UIWindowScene * scene = nil;
    for (UIWindowScene* wScene in [UIApplication sharedApplication].connectedScenes){
        if (wScene.activationState == UISceneActivationStateForegroundActive){
            scene = wScene;
            break;
        }
    }
    return scene.statusBarManager.statusBarFrame.size.height;
}

我認為以上也可以,@ChuckZHB 的回答。

這僅在您只有一個 window 應用程序時有效,它是所有移動應用程序和 99% 的 iPad 應用程序。

let height = UIApplication.shared.windows.first(where: \.isKeyWindow)?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

或者如果你想分解一下代碼:

let window = UIApplication.shared.windows.first(where: \.isKeyWindow)
let height = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

為我工作 iOS 15 歲及以上。

extension UIViewController {
    var statusBarHeight: CGFloat {
        guard
            let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
            let height = scene.statusBarManager?.statusBarFrame.height
        else {
            return 0
        }
        return height
    }
}

暫無
暫無

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

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