iOS 15下Navigation+TabView+Sheet组合使用时Detail视图自动弹出问题
问题原因
- 该问题是错误的视图层级结构导致的。SwiftUI官方推荐
TabView作为根视图,每个标签页单独持有自己的NavigationView,你将TabView嵌套在全局NavigationView内部的写法不符合规范。iOS 14对这种不规范结构的容错性较高可以正常运行,iOS 15优化了导航栈和标签栏的状态同步逻辑后,弹出Sheet触发视图重绘时,外层全局NavigationView会误判子视图状态,主动将Detail页从导航栈中弹出。 - 你之前设置
hidesBottomBarWhenPushed不生效,是因为这个属性需要在视图被push到导航栈之前完成配置,你在目标页面通过Introspect获取导航控制器时,push动作已经触发,设置时机太晚不会生效。
修复方案
iOS 15+可以直接使用SwiftUI原生的标签栏隐藏修饰符实现需求,无需引入第三方库,既不会触发页面自动弹出的问题,也能满足Detail页隐藏底部标签栏的交互要求,修改后的代码如下:
import Combine import SwiftUI import RealmSwift struct ContentView: View { var body: some View { // TabView作为根视图,每个标签持有独立NavigationView TabView { NavigationView { TabItemView(num: 1) } .tabItem { Text("One") } NavigationView { TabItemView(num: 2) } .tabItem { Text("Two") } } } } struct TabItemView: View { private let num: Int init(num: Int) { self.num = num } var body: some View { NavigationLink(destination: DetailView(text: "Detail View \(num)")) { Text("Go to Detail View") } } } struct DetailView: View { @State private var showingSheet = false private let text: String init(text: String) { self.text = text } var body: some View { Button("Open Sheet") { showingSheet.toggle() } // 隐藏当前页的底部标签栏 .toolbar(.hidden, for: .tabBar) .sheet(isPresented: $showingSheet) { Text("Sheet Text") } } }
如果需要兼容iOS 14及更低版本,可将隐藏标签栏的逻辑替换为Introspect的正确配置方式:在TabItemView的导航控制器中将下一级页面的hidesBottomBarWhenPushed设置为true即可。
内容的提问来源于stack exchange,提问作者skywalkerdude
相关产品推荐
相关产品推荐

