I have a simple app with two tab pages - preferences page and directory page. Directory page shows the name, address and other basic info about people (mock data) and preferences page displays toggles which should determine which fields about a person should be shown.
Disabling the toggles does not hide the disabled properties (e.g., name, address) shown on the directory page, and even logs a warning in the console: invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
ContentView (Root View of App - points to the two pages)
struct ContentView: View {
var body: some View {
TabView {
DirectoryView()
.tabItem {
Text("Directory")
Image(systemName: "list.bullet.rectangle.portrait")
}
PreferencesView()
.tabItem {
Text("Preferences")
Image(systemName: "gear")
}
}
.environmentObject(PreferencesModel())
}
}
DirectoryView (Displays people's info)
struct DirectoryView : View {
@EnvironmentObject var preferencesModel:PreferencesModel
let personModel = PersonModel()
var body: some View {
ScrollView {
ForEach(personModel.people) { person in
VStack(alignment: .leading) {
if preferencesModel.displayName {
HStack {
Text("Name: ")
.font(.body)
.fontWeight(.bold)
Text(person.name)
}
.frame(width: UIScreen.main.bounds.size.width, height: 20, alignment: .leading)
}
if preferencesModel.displayAddress {
HStack {
Text("Address: ")
.font(.body)
.fontWeight(.bold)
Text(person.address)
}
.frame(width: UIScreen.main.bounds.size.width, height: 20, alignment: .leading)
}
if preferencesModel.displayCompany {
HStack {
Text("Company: ")
.font(.body)
.fontWeight(.bold)
Text(person.company)
}
.frame(width: UIScreen.main.bounds.size.width, height: 20, alignment: .leading)
}
if preferencesModel.displayExperience {
HStack {
Text("Years of Experience: ")
.font(.body)
.fontWeight(.bold)
Text(String(person.yearsOfExperience))
}
.frame(width: UIScreen.main.bounds.size.width, height: 20, alignment: .leading)
}
}
.padding()
Divider()
}
}
}
}
PreferencesModel (ViewModel storing preferences around which fields to display)
class PreferencesModel: ObservableObject {
var displayName = true
var displayAddress = true
var displayCompany = true
var displayExperience = true
}
PreferencesView (View with the toggles)
struct PreferencesView: View {
@EnvironmentObject var preferencesModel:PreferencesModel
var body: some View {
ScrollView {
VStack {
Toggle("Name", isOn: $preferencesModel.displayName)
Toggle("Address", isOn: $preferencesModel.displayAddress)
Toggle("Company", isOn: $preferencesModel.displayCompany)
Toggle("Years of experience", isOn: $preferencesModel.displayExperience)
}
}
}
}
You are missing @Published
on the ObservableObject
variables. You should also put the initial PreferenceModel
in an @StateObject
in the ContentView
to protect it from re-creating.