Here is the code i am trying to reproduce.
The problem is that when you click on the link, the screen opens without animation and an error is generated in the console.
But if you go to another page Tab and go back, then everything works correctly.
var body: some View {
TabView {
//First Screen
NavigationView {
NavigationLink {
Text("Hello Page 1")
} label: {
Text("Page 1")
}
}
.navigationViewStyle(.stack)
.tag(1)
//Second Screen
NavigationView {
NavigationLink {
Text("Hello Page 2")
} label: {
Text("Page 2")
.foregroundColor(.green)
}
}
.navigationViewStyle(.stack)
.tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .always))
}
To correct this error you need to use individual structs in your TabView. In a real app, you would be doing this as a matter of course, and would not ever see this error. An example would be:
struct MyTabView: View {
var body: some View {
TabView {
Content1()
.tag(1)
Content2()
.tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .always))
}
}
struct Content1: View {
var body: some View {
NavigationView {
NavigationLink {
Text("Hello Page 1")
} label: {
Text("Page 1")
}
}
.navigationViewStyle(.stack)
}
}
struct Content2: View {
var body: some View {
NavigationView {
NavigationLink {
Text("Hello Page 2")
} label: {
Text("Page 2")
}
}
.navigationViewStyle(.stack)
}
}
NavigationView would go in each of these contained structs as they would be the top of the hierarchy for each tab.
Related
I have two views embedded in a TabView and a third view activated by a ToolbarItem in a navigationStack.
problem 1)
When I tap on plus button I navigate to my addView, but I still can see the tabs at the bottom.
problem 2)
after many test I found that if put the tabView code in MainView Inside a NavigationStack, I solve problem 1) but each time I dismiss from a detailView from a row in ContentView, the navigation Item disappears.
the main view for the tabview
struct MainView: View {
var body: some View {
TabView {
ContentView()
.tabItem {
Label("List", systemImage: "list.dash")
}
SettingsView()
.tabItem {
Label("Settings", systemImage: "gearshape.fill")
}
}
}
}
the ContentView (a list of lessons, navigationDestination goes to a detail view)
struct ContentView: View {
#Environment(\.managedObjectContext) var moc
#FetchRequest (sortDescriptors: [
SortDescriptor(\.lessonNuber, order: .reverse)
], predicate: nil) var lessons: FetchedResults<Lesson>
#State var showAddView = false
var body: some View {
NavigationStack {
VStack {
List {
ForEach(lessons, id: \.self) { lesson in
NavigationLink {
DetailView(lesson: lesson)
} label: {
HStack {
Text("\(lesson.lessonNuber)")
.font(.title)
Text( "\(lesson.un_notion)")
.font(.body)
}
}
}
}
// .background(
// NavigationLink(destination: AddView(), isActive: $showAddView) {
// AddView()
// }
// )
.navigationDestination(isPresented: $showAddView) {
AddView()
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
showAddView = true
} label: {
Label("Add Lesson", systemImage: "plus")
}
}
}
}
.padding()
}
}
}
I am presenting a view as an overlay but when I add a NavigationLink with a destination to that overlay view, the text is greyed out and tapping it does nothing. How do I proceed?
struct ContentView: View {
var body: some View {
NavigationView { }
.overlay(
VStack {
NavigationLink(destination: Text("Go to some view")) {
Text("NavigationLink in overlay")
}
Button {
print("button tapped")
} label: {
Text("Button in overlay")
}
}
)
}
}
Your NavigationLink is not inside the NavigationView! Try this:
struct ContentView: View {
var body: some View {
NavigationView {
Color.clear
.overlay(
VStack {
NavigationLink(destination: Text("Go to some view")) {
Text("NavigationLink in overlay")
}
Button {
print("button tapped")
} label: {
Text("Button in overlay")
}
}
)
}
}
}
My first view has a NavigationView with a Tab Bar View
struct TestView: View {
var body: some View {
NavigationView {
TabTestView()
}
}
}
In the Tab Bar, I have two views, say TestView1 and TestView2.
struct TabTestView: View {
var body: some View {
TabView {
TestView1()
.tabItem {
Label("Test 1", systemImage: "list.dash")
}
TestView2()
.tabItem {
Label("Test 2", systemImage: "plus")
}
}
}
}
I now need to add a toolbar button to TestView1. Here is my attempt to do so:
struct TestView1: View {
var body: some View {
Text("Hello World")
.navigationTitle("Test View 1")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save") {
print("Toolbar button click")
}
}
}
}
}
While this adds the Navigation Title to the page, the toolbar button is not added, as shown in the screenshot below:
If I, however, add the toolbar to the TabTestView, as below, the toolbar button does show up.
struct TabTestView: View {
var body: some View {
TabView {
TestView1()
.tabItem {
Label("Test 1", systemImage: "list.dash")
}
TestView2()
.tabItem {
Label("Test 2", systemImage: "plus")
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save") {
print("Toolbar button click")
}
}
}
}
}
This is a problem - the code to be executed on the button click depends upon variables in TestView1, and adding the toolbar to the TabTestView doesn't feel right, semantically the toolbar "belongs" in TestView1.
Any thoughts would be greatly appreciated.
Once I had working code, I realized I had seen this before. It appears to be a bug in SwiftUI. TabView and NavigationView don't play well together. You will find a lot of my answer will say one NavigationViews at the top of the view hierarchy, which is what you have done. That will not work in this instance. The workaround is to put a NavigationViews in each of the views in the tabs separately for this to work. You will still get all of the correct NavigationViews behavior for each of those hierarchies, but it is duplicative. I don't think I ever filed a Radar on it, but I will today and will post the Radar number here.
struct TestView: View {
var body: some View {
// NavigationView { //Remove this NavigationView
TabTestView()
// }
}
}
struct TabTestView: View {
var body: some View {
TabView {
TestView1()
.tabItem {
Label("Test 1", systemImage: "list.dash")
}
TestView2()
.tabItem {
Label("Test 2", systemImage: "plus")
}
}
}
}
struct TestView1: View {
var body: some View {
NavigationView { // Add here
Text("Hello World 1")
.navigationTitle("Test View 1")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save") {
print("Toolbar button click")
}
}
}
}
}
}
struct TestView2: View {
var body: some View {
NavigationView { // Add here
Text("Hello World 2")
.navigationTitle("Test View 2")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save") {
print("Toolbar button click")
}
}
}
}
}
}
The Radar number is FB9727010.
I am wrapping my navigaton view inside a tab view.
but when I load the app, my navigation view is always going to its next page by default.
How can I stop this ? I spent so much time but could not figure it out.
here is my view
ZStack {
Color.red
.edgesIgnoringSafeArea(.all)
VStack {
TabView(selection:$selectedTab) {
NavigationView {
VStack {
Text("Hello")
}
.edgesIgnoringSafeArea(.all)
}
.tag(1)
VStack {
Text("Two")
}
.tag(2)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
FirstView is a navigation view like this
NavigationView {
VStack {
...
}
.sheet(isPresented: $myForm, onDismiss:{ }) {
NewFormView(...)
}
.navigationBarHidden(true)
}
It appears like this
XCode11 beta3,
MacOS Catalina 10.15 Beta(19A501i)
I want to hide tabBar when push~ Any command will very helpful, Thanks~
Click me to show gif image
:
struct ContentView : View {
var body: some View {
WhenNavigationViewIsRootView()
}
}
struct WhenNavigationViewIsRootView : View {
var body: some View {
NavigationView {
TabbedView{
Rectangle().foregroundColor(.green)
.tag(0).tabItem{Text("Page1")}
VStack {
List {
ForEach(0...2) { i in
NavigationLink(
destination: Text("\(i)"),
label: {Text("\(i)")})
}
}
}.tag(1).tabItem{Text("Page2")}
}
.navigationBarHidden(true)
}
}
}
If you want to hide the navigation bar in a TabbedView, you have to set .navigationBarHidden(true) on the views nested inside TabbedView. This isn't enough, however. For whatever reason, SwiftUI requires that you first set the navigation bar title before you can hide the navigation bar.
NavigationView {
TabbedView{
Rectangle()
.foregroundColor(.green)
.tag(0)
.tabItem{
Text("Page1")
}
.navigationBarTitle("")
.navigationBarHidden(true)
List(0...2) { i in
NavigationLink(destination: Text("\(i)")) {
Text("\(i)")
}
}
.tag(1)
.tabItem {
Text("Page2")
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}