iOS15下iPhone XR设备AVCam预览层覆盖导航栏问题咨询
iOS 15 下 AVCam 预览与导航栏重叠问题原因分析
核心触发原因
- iOS 15 导航栏默认逻辑变更
iOS 15 正式废弃了原有
UINavigationBar的translucent属性默认判定规则,新增的scrollEdgeAppearance属性默认配置为全透明样式。同时系统对edgesForExtendedLayout布局延伸规则做了调整:仅当视图控制器根视图为 UIScrollView 及其子类时,自动适配导航栏显示范围;自定义的AVCaptureVideoPreviewLayer不属于滚动视图子类,旧款设备上系统会误判布局延伸范围,导致预览层顶部锚点对齐屏幕顶部而非导航栏底部。
- 不同机型的安全区计算逻辑差异
iPhone XR 为 A12 芯片的旧款刘海机型,iOS 15 对 A12 及更早芯片的刘海设备safeAreaInsets计算做了兼容性调整,仅保留 A14 及以上芯片机型(如 iPhone 12 系列)的原有布局判定逻辑。旧款设备的安全区顶部 inset 计算会忽略导航栏的显示高度,仅返回刘海高度,导致预览层布局时参照的顶部安全区数值小于实际导航栏+刘海的总高度,最终出现重叠。 - AVCam 预览层布局时机偏差
如果预览层布局逻辑写在viewDidLoad或viewWillAppear生命周期节点,iOS 15 上旧款设备的导航栏高度在这两个节点尚未完成最终计算,此时拿到的导航栏高度为错误值,也会触发布局偏移。iPhone 12 设备的布局计算优先级更高,不会出现该时机偏差问题。
修复参考方案
- 强制导航栏使用不透明样式,关闭布局延伸适配
// Objective-C 示例 if (@available(iOS 15.0, *)) { UINavigationBarAppearance *app = [[UINavigationBarAppearance alloc] init]; [app configureWithOpaqueBackground]; self.navigationController.navigationBar.standardAppearance = app; self.navigationController.navigationBar.scrollEdgeAppearance = app; }
// Swift 示例 if #available(iOS 15.0, *) { let app = UINavigationBarAppearance() app.configureWithOpaqueBackground() navigationController?.navigationBar.standardAppearance = app navigationController?.navigationBar.scrollEdgeAppearance = app }
- 关闭当前视图控制器的布局延伸属性
self.edgesForExtendedLayout = UIRectEdgeNone; - 调整预览层约束锚点,直接绑定导航栏底部
[previewView.topAnchor constraintEqualToAnchor:self.navigationController.navigationBar.bottomAnchor constant:0].active = YES;
内容的提问来源于stack exchange,提问作者Icare
相关产品推荐
相关产品推荐

