I currently have an application with 4 tab views
Content View:
import SwiftUI
struct ContentView: View {
init() {
//Setting appearance of UI colour
UITabBar.appearance().backgroundColor = ColourManager.UIColour1
}
var body: some View {
TabView {
ProfileView().tabItem ({
Text("Profile")
}).tag(0)
TrackerView().tabItem ({
Text("Tracker")
}).tag(1)
ProgressView().tabItem ({
Text("Progress")
}).tag(2)
MealView().tabItem ({
Text("Meals")
}).tag(3)
}.accentColor(ColourManager.Colour3)
}
}
And I have the following class which is my model:
import Foundation
class UserInfoModel: ObservableObject {
struct UserInfo: Identifiable {
var id = UUID()
var height: Int
var weight: Int
var gender: String
var age: Int
}
struct DailyCalorieGoals: Identifiable{
var id = UUID()
var calorieGoal: Int
var fatGoal: Int
var proteinGoal: Int
var carbGoal: Int
}
struct CurrentCalorieProgress: Identifiable{
var id = UUID()
var calorieProgress: Int
var fatProgress: Int
var proteinGoal: Int
}
@Published var person1 = UserInfo.init(height: 20, weight: 30, gender: "male", age: 5)
}
Now what I am trying to do is create a single instance of this class and have all my views access the same object using Observable Object, however in my first view, I set the weight to a new value to check if it maintains that state in my other view:
ProfileView
@ObservedObject var person = UserInfoModel()
var body: some View {
Button(action: {
print(self.person.person1.weight)
self.person.person1.weight = 100
print(self.person.person1.weight)
}) {
Text("Button")
}
.foregroundColor(ColourManager.Colour1)
}
}
Which changes the value of weight to 100 but when I go to another tab screen, and instantiate the object again, the value goes back to the one declared in the model class:
@ObservedObject var person = UserInfoModel()
var body: some View {
Button(action: {
print(person.person1.weight)
}) {
Text("Button")
}
.foregroundColor(ColourManager.Colour1)
}
}
So I essentially want to just instantiate one object, and be able to manipulate it and change the values in all views and update the UI automatically, any help would be greatly appreciated!
2
Answers
Thats because you are creating a new instance of
UserInfoModel
for each view .. you have to create that once in the first view and pass it to your subviews as parameter or even as environment object.And in your ContentView you will create that Model once
1. Using ObservedObject
@ObservedObject
is used to keep track of an object that has already been created, probably using@StateObject
.You have to create the
person
variable in theContentView
, where theTabView
is createdAnd pass it as a parameter to each View from the
TabView
And now in each view you remove the instantiation of
person
variable, you keep just the declaration2. Using EnvironmentObject
@EnvironmentObject
is recommended for those scenarios where you need to use an@ObservableObject
but the views aren’t direct parent/child pairs.In your
App
file you’d have to create theperson
object:And the pass it to the
ContentView
like this:To use the object in any view that is within
ContentView
, you do this: