[英]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
屬性。 這是在UIWindow
的windowScene
上定義的。
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
}()
我不確定 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.