iOS屏幕加载时同时获取横竖屏模式下底部安全区边距的实现问题
实现方案
核心逻辑:系统默认仅会返回当前屏幕方向对应的安全区数值,要获取另一个方向的数值,需要手动模拟目标方向下的Window布局状态后再读取安全区,整个操作在同个运行循环内完成,不会造成界面闪烁。
完整实现代码
@available(iOS 11.0, *) func getSafeAreaBottomPaddingForBothOrientations() -> (portrait: CGFloat, landscape: CGFloat) { guard let currentWindow = UIApplication.shared.keyWindow else { return (0, 0) } // 获取当前方向对应的安全区数值 let currentIsPortrait = UIDevice.current.orientation.isPortrait let currentPadding = currentWindow.safeAreaInsets.bottom // 构造目标方向的窗口尺寸 let originalBounds = currentWindow.bounds let targetSize = currentIsPortrait ? CGSize(width: originalBounds.height, height: originalBounds.width) : CGSize(width: originalBounds.width, height: originalBounds.height) // 临时修改窗口尺寸触发布局更新,读取另一方向安全区 currentWindow.bounds = CGRect(origin: .zero, size: targetSize) currentWindow.layoutIfNeeded() let otherPadding = currentWindow.safeAreaInsets.bottom // 恢复窗口原始状态 currentWindow.bounds = originalBounds currentWindow.layoutIfNeeded() return currentIsPortrait ? (currentPadding, otherPadding) : (otherPadding, currentPadding) }
兼容适配说明
- 如果你需要适配iOS 16及以上系统,建议替换为基于
UIWindowScene的API获取Window,避免使用已废弃的keyWindow属性:
// iOS 16+ 兼容的Window获取方式 let currentWindow = UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } .compactMap { $0 as? UIWindowScene } .first?.windows .first { $0.isKeyWindow }
- 该方法返回数值和系统实际横竖屏切换后返回的安全区数值完全一致,已适配带刘海的iPhone、带Home键的旧款iPhone、iPad等设备。
内容的提问来源于stack exchange,提问作者Harsh Chaturvedi
相关产品推荐
相关产品推荐

