Hi everyone, I following 100 days of SwiftUI course , I used same idea of iExpense project exactly but without .sheet method, The list isn't updating when I add new item from AddView.
struct MainView: View {
var body: some View {
TabView {
ContentView()
.tabItem {
Image(systemName: "1.lane")
Text("One")
}
AddView(expenses: Expenses())
.tabItem {
Image(systemName: "2.lane")
Text("Two")
}
}
}
}
other codes same as iExpense project...
How to fix that ?
The project in GitHub: https://github.com/mahoozi97/iExpense-project
Thanks in advance
I got the solution.
Changes to MainView:
struct MainView: View {
// Create your expenses object in the main view
@StateObject var expenses = Expenses()
// This is necessary for switching between tabs
@State var selectedTab = 0
var body: some View {
// Use selection initializer for TabView
TabView(selection: $selectedTab) {
ContentView()
.tabItem {
Image(systemName: "1.lane")
Text("One")
}
// we assign tag to programmatically switch between tabs
.tag(1)
// Also we pass selectedTab to AddView so that we can go back to ContentView programmatically
AddView(selectedTab: $selectedTab)
.tabItem {
Image(systemName: "2.lane")
Text("Two")
}
// we assign tag to programmatically switch between tabs
.tag(2)
}
// Inject expenses object into environment so that ContentView and AddView can access it
.environmentObject(expenses)
}
}
Changes to ContentView:
struct ContentView: View {
// This is how we can access expenses object in the environment
@EnvironmentObject var expenses: Expenses
var body: some View {
NavigationView {
List {
ForEach(expenses.items, id: \.id) { item in
HStack {
VStack(alignment: .leading) {
{....same......}
// Pay attention that you need to add .environmentObject in previews to make it work
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(Expenses())
}
}
Changes to AddView:
struct AddView: View {
// This is how we can access expenses object in the environment
@EnvironmentObject var expenses: Expenses
@State private var name = ""
@State private var type = "personal"
@State private var amount = 0.0
// Here we pass selectedTab binding
@Binding var selectedTab: Int
let types = ["Business", "Personal"]
@Environment(\.dismiss) var dismiss
var body: some View {
NavigationView {
Form {
TextField("name", text: $name)
Picker("Type", selection: $type) {
ForEach(types, id: \.self) {
Text($0)
}
}
TextField("Amount", value: $amount, format: .currency(code: Locale.current.currency?.identifier ?? "BD"))
.keyboardType(.decimalPad)
}
.navigationTitle("Add new expense")
.toolbar {
Button("Save") {
let item = ExpenseItem(name: name, type: type, amount: amount)
expenses.items.append(item)
// This is how we jump back to ContentView upon pressing save
selectedTab = 1
}
}
}
}
}
// Pay attention that you need to add .environmentObject in previews to make it work
struct AddView_Previews: PreviewProvider {
static var previews: some View {
AddView(selectedTab: .constant(2))
.environmentObject(Expenses())
}
}
I got it from : https://www.hackingwithswift.com/forums/swiftui/list-isn-t-updating-when-i-add-a-new-item/23977/23981