iOS15起根视图Blur Effect为0时Status Bar折叠、导航栏失效问题
问题原因
这个异常是iOS 15对SwiftUI视觉效果渲染的优化逻辑漏洞导致的:
- 当模糊半径为0时,系统为了节省性能会直接跳过模糊效果图层的渲染,这个优化会错误触发Root View的安全区计算逻辑,导致顶部状态栏高度的Inset被误算为0,导航栏没有了顶部安全区的适配,自然就偏移到了状态栏下方,同时交互响应链也会因为图层计算错误失效。
- 这个逻辑也符合你观测到的scenePhase切换现象:当进入inactive状态时模糊半径为16,系统不会跳过模糊图层渲染,安全区计算正常,导航栏就会回到正确位置。
- 当你把模糊半径设为0.001时,只要数值大于0,系统就不会跳过模糊图层的渲染,安全区计算逻辑就会正常执行,所以问题消失。
推荐解决方案
方案1:极小值兼容(最快捷)
直接将active状态下的模糊半径设置为0.001,这个数值人眼完全无法识别,不会影响视觉效果,改动成本最低:
case .active : withAnimation { blurRadius = 0.001 }
方案2:调整模糊实现逻辑(最稳定)
不要直接给整个Root View添加模糊效果,改为用覆盖层实现模糊,完全规避原视图的安全区计算受影响:
struct RootView: View { @Environment(\.scenePhase) var scenePhase @State private var showBlur = false var body: some View { Group { OtherViews() } .overlay { if showBlur { Rectangle() .fill(.ultraThinMaterial) .opacity(0.9) .ignoresSafeArea() } } .onChange(of: scenePhase) { newValue in withAnimation { showBlur = newValue != .active } } } }
如果需要自定义模糊半径,可以封装UIVisualEffectView来实现更灵活的模糊控制,不会影响原视图的布局计算。
内容的提问来源于stack exchange,提问作者christophriepe
相关产品推荐
相关产品推荐

