当视图位于 SwiftUI 中的 TabView 中时,NavigationView 标题不会出现
NavigationView title doesn't appear when the views are in TabView in SwiftUI
我有两个视图,每个视图都包含带标题的 NavigationView。我创建了一个 TabBar 视图,它上面还有一个 NavigationView。
struct TabbarView: View {
var body: some View {
NavigationView{
TabView {
MainContentView()
.tabItem {
VStack {
Text("Main")
}
}.tag(0)
SearchContentView()
.tabItem {
VStack {
Text("Search")
}
}.tag(1)
}
}.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}
}
我试过隐藏此视图的导航栏,但没有用。仅显示此视图的导航栏。
这是MainContentView()
struct MainContentView: View {
var body: some View {
NavigationView {
Text("Some Content View")
}
.navigationBarTitle("Travel")
}
}
知道如何解决这个问题。谢谢!
更新:
基本上,当我点击 Log In 按钮时,我会通过 NavigationLink 传递 TabBarView()。
NavigationLink(destination: TabbarView()) {
HStack {
Text("Log In")
}
.padding()
.frame(width: geometry.size.width - 40, height: 40)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(5)
}.padding(.bottom, 40)
这样做时,它显示了具有 child 视图的 TabbarView() 这就是我所看到的:
"Travel" 上方的 space(childView 的 navigationBarTitle)是标签栏的 navigationBar,因为我将其推入 navigationStack。
这里首先要指出的是,代码中的所有导航栏修饰符都应该是 NavigationView
内部视图的修饰符,而不是 NavigationView
本身的修饰符。来自 .navigationBarTitle
的文档,例如:
This modifier only takes effect when this view is inside of and visible within a NavigationView.
此外,不需要 NavigationView
包裹您的 TabView
,然后在您的 MainContentView
内包裹另一个。这只会导致嵌套的导航栏,你绝对不希望这样。相反,只需使用一个 NavigationView
。我还建议您不要将 NavigationView
放在 MainContentView
正文中。
我重构了您的代码以显示我在说什么,尽管我不确定您在何处尝试使用 .navigationBarBackButtonHidden
和 .navigationBarHidden
,因此我省略了它们。请记住,它们的功能就像 .navigationBarTitle
- 您需要将它们用作 NavigationView
内视图的修饰符,而不是 NavigationView
本身。
struct TabBarView: View {
var body: some View {
TabView {
NavigationView {
MainContentView()
}
.tag(0)
.tabItem {
Text("Main")
}
SearchContentView()
.tag(1)
.tabItem {
Text("Search")
}
}
}
}
struct MainContentView: View {
var body: some View {
Text("Some Content View")
.navigationBarTitle("Travel")
}
}
您可能会注意到,我还从 .tabItem
中删除了 VStack
。您可以将 Text
和 Image
都放在 .tabItem
中而不需要 VStack
,如果我没记错的话,.tabItem
会忽略任何不是Text
或 Image
无论如何。
如果您需要 Login/SignUp 在 tabview 之前查看,请不要使用 NavigationView 对其进行包装。在 Login/Sign 向上视图
@EnvironmentObject var authService:AuthService
var body: some View{
ZStack{
if(!authService.isSignedIn){
Button(action: {
self.authService.signIn()
}) {
Text("Login")
}
}
else{
TabBarView()
}
}
}
在子视图中,您可以使用 @EnvironmentObject
控制 isSignedIn 变量,并在退出时更改该值
这是之前使用的TabBarView()
的例子:
var body: some View {
TabView {
NavigationView{
FirstView()
}
.tabItem {
VStack{
Image("first")
Text("First")
}
}
NavigationView{
SecondView()
}
.tabItem {
VStack{
Image("second")
Text("Second")
}
}
}
}
这可能是以下选项卡视图之一:
@EnvironmentObject var authService:AuthService
var body: some View {
TextView("Hello World")
.navigationBarItems(trailing: LogOutButton(logOutFunction: authService.signOut))
}
这也适用于 iOS 13:
var body: some View {
TabView {
NavigationView {
FirstTabbarView(viewModel: viewModel)
.navigationBarTitle("NavBar title Tabbar1", displayMode: .inline)
}
.tabItem {
Image(systemName: "house.fill")
Text("Tab bar 1")
}
NavigationView {
SecondTabbarView(viewModel: viewModel)
.navigationBarTitle("Navbar title Tabbar 2", displayMode: .inline)
}
.tabItem {
Image(systemName: "person.fill")
Text("Tab bar 2")
}
}
}
我有两个视图,每个视图都包含带标题的 NavigationView。我创建了一个 TabBar 视图,它上面还有一个 NavigationView。
struct TabbarView: View {
var body: some View {
NavigationView{
TabView {
MainContentView()
.tabItem {
VStack {
Text("Main")
}
}.tag(0)
SearchContentView()
.tabItem {
VStack {
Text("Search")
}
}.tag(1)
}
}.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}
}
我试过隐藏此视图的导航栏,但没有用。仅显示此视图的导航栏。
这是MainContentView()
struct MainContentView: View {
var body: some View {
NavigationView {
Text("Some Content View")
}
.navigationBarTitle("Travel")
}
}
知道如何解决这个问题。谢谢!
更新: 基本上,当我点击 Log In 按钮时,我会通过 NavigationLink 传递 TabBarView()。
NavigationLink(destination: TabbarView()) {
HStack {
Text("Log In")
}
.padding()
.frame(width: geometry.size.width - 40, height: 40)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(5)
}.padding(.bottom, 40)
这样做时,它显示了具有 child 视图的 TabbarView() 这就是我所看到的: "Travel" 上方的 space(childView 的 navigationBarTitle)是标签栏的 navigationBar,因为我将其推入 navigationStack。
这里首先要指出的是,代码中的所有导航栏修饰符都应该是 NavigationView
内部视图的修饰符,而不是 NavigationView
本身的修饰符。来自 .navigationBarTitle
的文档,例如:
This modifier only takes effect when this view is inside of and visible within a NavigationView.
此外,不需要 NavigationView
包裹您的 TabView
,然后在您的 MainContentView
内包裹另一个。这只会导致嵌套的导航栏,你绝对不希望这样。相反,只需使用一个 NavigationView
。我还建议您不要将 NavigationView
放在 MainContentView
正文中。
我重构了您的代码以显示我在说什么,尽管我不确定您在何处尝试使用 .navigationBarBackButtonHidden
和 .navigationBarHidden
,因此我省略了它们。请记住,它们的功能就像 .navigationBarTitle
- 您需要将它们用作 NavigationView
内视图的修饰符,而不是 NavigationView
本身。
struct TabBarView: View {
var body: some View {
TabView {
NavigationView {
MainContentView()
}
.tag(0)
.tabItem {
Text("Main")
}
SearchContentView()
.tag(1)
.tabItem {
Text("Search")
}
}
}
}
struct MainContentView: View {
var body: some View {
Text("Some Content View")
.navigationBarTitle("Travel")
}
}
您可能会注意到,我还从 .tabItem
中删除了 VStack
。您可以将 Text
和 Image
都放在 .tabItem
中而不需要 VStack
,如果我没记错的话,.tabItem
会忽略任何不是Text
或 Image
无论如何。
如果您需要 Login/SignUp 在 tabview 之前查看,请不要使用 NavigationView 对其进行包装。在 Login/Sign 向上视图
@EnvironmentObject var authService:AuthService
var body: some View{
ZStack{
if(!authService.isSignedIn){
Button(action: {
self.authService.signIn()
}) {
Text("Login")
}
}
else{
TabBarView()
}
}
}
在子视图中,您可以使用 @EnvironmentObject
控制 isSignedIn 变量,并在退出时更改该值
这是之前使用的TabBarView()
的例子:
var body: some View {
TabView {
NavigationView{
FirstView()
}
.tabItem {
VStack{
Image("first")
Text("First")
}
}
NavigationView{
SecondView()
}
.tabItem {
VStack{
Image("second")
Text("Second")
}
}
}
}
这可能是以下选项卡视图之一:
@EnvironmentObject var authService:AuthService
var body: some View {
TextView("Hello World")
.navigationBarItems(trailing: LogOutButton(logOutFunction: authService.signOut))
}
这也适用于 iOS 13:
var body: some View {
TabView {
NavigationView {
FirstTabbarView(viewModel: viewModel)
.navigationBarTitle("NavBar title Tabbar1", displayMode: .inline)
}
.tabItem {
Image(systemName: "house.fill")
Text("Tab bar 1")
}
NavigationView {
SecondTabbarView(viewModel: viewModel)
.navigationBarTitle("Navbar title Tabbar 2", displayMode: .inline)
}
.tabItem {
Image(systemName: "person.fill")
Text("Tab bar 2")
}
}
}