When I initially run the application, I have the add button present on the first tab, on the second tab, the add button shouldnt be visible but when I tab back to the first tab, the button is gone. Here is my code for ListView and ContentView. I am trying to figure out a way to use the tags setup to hide the toolbar add button that would automatically update the UI.
struct TaskListView: View {
@ObservedObject var taskStore: TaskStore
@State private var selectedTab: Tab = .tasks
enum Tab {
case tasks
case completed
}
var body: some View {
TabView {
List(taskStore.tasks.filter { !$0.isCompleted }, id: \.self) { task in
NavigationLink(value: task) {
VStack {
TaskRowView(task: task)
}
.padding([.leading, .trailing], 20)
}
.navigationDestination(for: Task.self) { task in
TaskDetailView(task: $taskStore.tasks
.first(where: { $0.id == task.id })!)
}
}
.tabItem {
Image(systemName: "list.bullet.circle")
Text("Tasks")
}
.tag(Tab.tasks)
.toolbar(.visible, for: .navigationBar)
List(taskStore.tasks.filter { $0.isCompleted }, id: \.self) { task in
NavigationLink(value: task) {
VStack {
TaskRowView(task: task)
}
.padding([.leading, .trailing], 20)
}
.navigationDestination(for: Task.self) { task in
TaskDetailView(task: $taskStore.tasks
.first(where: { $0.id == task.id })!)
}
}
.tabItem {
Image(systemName: "checkmark.circle")
Text("Completed")
}
.tag(Tab.completed)
.toolbar(.hidden, for: .navigationBar)
}
}
}
struct TaskListView_Previews: PreviewProvider {
static var previews: some View {
TaskListView(taskStore: TaskStore())
}
}
Contentview file:
import SwiftUI
struct ContentView: View {
@StateObject var taskStore = TaskStore()
var body: some View {
NavigationStack {
VStack {
if taskStore.tasks.isEmpty {
Text("No tasks found")
} else {
TaskListView(taskStore: taskStore)
}
Spacer()
//NewTaskButton(addingTask: $addingTask)
}
.navigationTitle("My Tasks")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NewTaskButtonView(taskStore: taskStore)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The TabBar
should always be on top of the view hierarchy.
TabView
/ \
Navigation Navigation
| |
List1 List2
Following your requirements, I would prefer to refactor your code as below.
Firstly, break into two lists, IncompleteTaskView
and CompletedTaskView
. You're using taskStore
for displaying purpose only so I will use normal variable. You may need to change to @Enviroment
object later if needed.
struct IncompleteTaskView: View {
var taskStore: TaskStore
var body: some View {
NavigationStack {
VStack {
...
}
.navigationTitle("Incomplete Tasks")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NewTaskButtonView(taskStore: taskStore)
}
}
}
}
}
The same implementation with CompletedTaskView
, except .toolBar
.
Secondly, the ContentView
will have TabView
only:
struct ContentView: View {
...
@StateObject private var taskStore = TaskStore()
var body: some View {
TabView(selection: $selectedTab) {
IncompleteTaskView(taskStore: taskStore)
.tabItem {
Image(systemName: "list.bullet.circle")
Text("Tasks")
}
.tag(Tab.tasks)
CompletedTaskView(taskStore: taskStore)
.tabItem {
Image(systemName: "checkmark.circle")
Text("Completed")
}
.tag(Tab.completed)
}
}
}
}