iPhoneX中如何移除应用UIWindow的底部内边距?多窗口适配问题
解决iPhoneX及后续设备底部UIWindow内边距问题
针对你提到的双UIWindow布局(顶部主体窗口+底部横幅窗口)在iPhoneX及带安全区设备上出现底部内边距的问题,我之前处理过类似场景,这里给你几个实用的解决思路:
方案一:调整底部窗口RootViewController的布局规则,忽略安全区
如果你的底部横幅是放在窗口的rootViewController视图里,默认情况下视图会遵循系统的safeAreaInsets,导致底部留出空白。可以通过以下方式修改:
- 在底部窗口的rootViewController中,设置
edgesForExtendedLayout = .all(至少包含.bottom),让视图延伸覆盖整个窗口(包括安全区范围)。 - 给横幅视图添加约束时,直接绑定到view的底部边缘,而非
safeAreaLayoutGuide.bottomAnchor。
示例代码:
class BannerViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 允许视图延伸到安全区外 edgesForExtendedLayout = .all // 创建并配置横幅视图 let bannerView = UIView() bannerView.backgroundColor = .systemRed bannerView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(bannerView) // 绑定约束到view底部,无视安全区 NSLayoutConstraint.activate([ bannerView.leadingAnchor.constraint(equalTo: view.leadingAnchor), bannerView.trailingAnchor.constraint(equalTo: view.trailingAnchor), bannerView.bottomAnchor.constraint(equalTo: view.bottomAnchor), bannerView.heightAnchor.constraint(equalToConstant: 60) ]) } }
方案二:直接重置底部窗口的safeAreaInsets(iOS11+)
如果希望整个底部窗口都忽略安全区,可以直接将窗口的safeAreaInsets设为零,这样窗口内的所有布局都会无视安全区的存在:
let bottomWindow = UIWindow(frame: UIScreen.main.bounds) if #available(iOS 11.0, *) { bottomWindow.safeAreaInsets = UIEdgeInsets.zero } // 后续设置rootViewController、windowLevel等操作
这个方法刚好覆盖iPhoneX及以后的设备,完美匹配你的需求场景。
方案三:动态计算窗口frame,强制覆盖安全区
如果你的底部窗口原本没有占满整个屏幕,可以动态获取底部安全区高度,调整窗口frame让它延伸到屏幕最底部:
let screenBounds = UIScreen.main.bounds var bottomSafeAreaHeight: CGFloat = 0 if #available(iOS 11.0, *) { bottomSafeAreaHeight = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0 } // 假设横幅窗口高度为60,调整frame让窗口覆盖安全区 let bottomWindowFrame = CGRect( x: 0, y: screenBounds.height - 60, width: screenBounds.width, height: 60 + bottomSafeAreaHeight ) let bottomWindow = UIWindow(frame: bottomWindowFrame)
额外注意事项
- 记得设置底部窗口的
windowLevel(比如UIWindowLevelNormal + 1),确保它不会被顶部主体窗口遮挡。 - 测试时要覆盖iPhoneX、XS、XR、11及以后的全系列设备,保证布局在不同机型上表现一致。
内容的提问来源于stack exchange,提问作者Marksss
相关产品推荐
相关产品推荐

