SwiftUI中TabView标签项超5个时出现多个返回按钮的问题解决
问题描述
当TabView中的标签项数量超过5个时,SwiftUI会自动生成一个More按钮,但这引发了不符合预期的行为:进入第6个标签页时,导航栏同时显示< 6和< More两个返回按钮,而非仅显示< 6。
复现代码如下:
import SwiftUI struct ContentView: View { @State var value: String = "" var body: some View { TabView{ NavigationView{ Text("1") .navigationTitle("1") } .tabItem{ Text("1") } NavigationView{ Text("2") .navigationTitle("2") } .tabItem{ Text("2") } NavigationView{ Text("3") .navigationTitle("3") } .tabItem{ Text("3") } NavigationView{ Text("4") .navigationTitle("4") } .tabItem{ Text("4") } NavigationView{ Text("5") .navigationTitle("5") } .tabItem{ Text("5") } NavigationView{ Section{ Form{ Picker("Value", selection: $value){ Text("1").tag("1") } } } .navigationTitle("6") } .tabItem{ Text("6") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
问题原因
当TabView的标签数量超过5个时,系统会自动将第6个及之后的标签页包裹在一个系统自带的NavigationController中,用于实现More页面的跳转逻辑。而我们在每个标签页内部又手动嵌套了NavigationView,这就造成了双层导航栈嵌套:外层是系统的NavigationController,内层是我们自己添加的NavigationView。当进入第6个标签页时,两个导航栈都会显示各自的返回按钮,最终出现两个返回按钮的问题。
修复方案
解决思路是避免导航栈嵌套,有两种可行方式:
方式一:将NavigationView提升到TabView外层
把整个TabView包裹在一个NavigationView中,所有标签页共享同一个导航栈,系统的More页面跳转不会产生冲突:
import SwiftUI struct ContentView: View { @State var value: String = "" var body: some View { NavigationView { TabView{ Text("1") .navigationTitle("1") .tabItem{ Text("1") } Text("2") .navigationTitle("2") .tabItem{ Text("2") } Text("3") .navigationTitle("3") .tabItem{ Text("3") } Text("4") .navigationTitle("4") .tabItem{ Text("4") } Text("5") .navigationTitle("5") .tabItem{ Text("5") } Section{ Form{ Picker("Value", selection: $value){ Text("1").tag("1") } } } .navigationTitle("6") .tabItem{ Text("6") } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
方式二:给超过5个的标签页隐藏系统导航栏
如果必须给每个标签页单独使用NavigationView,可以在第6个及之后的标签页中,手动隐藏系统自带的导航栏,只保留自定义NavigationView的导航栏:
import SwiftUI struct ContentView: View { @State var value: String = "" var body: some View { TabView{ NavigationView{ Text("1") .navigationTitle("1") } .tabItem{ Text("1") } NavigationView{ Text("2") .navigationTitle("2") } .tabItem{ Text("2") } NavigationView{ Text("3") .navigationTitle("3") } .tabItem{ Text("3") } NavigationView{ Text("4") .navigationTitle("4") } .tabItem{ Text("4") } NavigationView{ Text("5") .navigationTitle("5") } .tabItem{ Text("5") } NavigationView{ Section{ Form{ Picker("Value", selection: $value){ Text("1").tag("1") } } } .navigationTitle("6") } .tabItem{ Text("6") } // 隐藏系统自带的导航栏 .navigationBarHidden(true) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

