SwiftUI使用simultaneousGesture触发视图模糊时子视图自动上移问题求解
问题原因
这是Xcode 13.0 beta 5对应的iOS 15测试版中SwiftUI的已知实现缺陷:当对包含NavigationView、TabView且设置了ignoresSafeArea的根视图应用动态模糊半径变化时,SwiftUI重绘视图计算布局会错误忽略底部安全区高度,导致整体内容上移对应高度(通常为底部Tab栏或Home指示器的高度)。
你提到的效果对比如下:

解决方案
可任选以下任意一种方案修复问题:
- 调整blur修饰符的挂载位置:不要直接给根ZStack添加blur,改为给ZStack内部的所有子元素分别添加blur,避免触发根视图布局重计算的bug,修改示例如下:
ZStack{ TabView(selection: $select){ FirstNav().tabItem{ Label("aa",systemImage: "folder") }.tag(1) Text("bb").tabItem{ Label("bb",systemImage: "folder") }.tag(2) Text("cc").tabItem{ Label("cc",systemImage: "folder") }.tag(3) }.blur(radius: ifBlur ? 2: 0) Button(action: { }) { Text("Button") }.simultaneousGesture(DragGesture(minimumDistance: 0, coordinateSpace: .global).onChanged { value in ifBlur = true }.onEnded { value in ifBlur = false }).blur(radius: ifBlur ? 2: 0) } // 根ZStack不再挂载blur修饰符
- 给根ZStack显式声明忽略所有安全区:在blur修饰符前添加
.ignoresSafeArea(),强制视图布局计算时统一安全区规则,避免模糊触发时的布局偏移。 - 禁止模糊状态切换的隐式动画:给blur修饰符绑定无动画规则,规避状态切换动画过程中的布局异常,修改如下:
}.blur(radius: ifBlur ? 2: 0) .animation(.none, value: ifBlur)
内容的提问来源于stack exchange,提问作者yimkong
相关产品推荐
相关产品推荐

