Home > Enterprise >  Changing a boolean in a variable from Identifiable struct
Changing a boolean in a variable from Identifiable struct

Time:09-22

import Foundation

struct Person: Identifiable{
    let id = UUID()
    var name: String
    var age: Int
    var job: String
    var myPerson: Bool
}

class Model: ObservableObject {
    @Published var people: [Person] = []
    @Published var myPeople: [Person] = []
    
    init(){
        addPeople()
    }
    
    func addPeople(){
        people = peopleData
        myPeople = peopleData.filter { $0.myPerson }
    }
}

var peopleData = [
    person(name: "Bob", age: 22, job: "Student", myPerson: false),
    person(name: "John", age: 26, job: "Chef", myPerson: false)
]

I edit the question and my arrays are @Published already. Should I chance peopleData directly or I am doing mistake another where.

import SwiftUI

struct ContentView: View {
    
    @StateObject var model = Model()
    
    var body: some View {
        
        VStack {
            VStack {
                ForEach(model.myPeople) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)")
                        Text("Age: \(person.age)")
                        Text("Age: \(person.job)")
                    }.padding()
                }
            }
            VStack {
                ForEach(model.people) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)")
                        Text("Age: \(person.age)")
                        Text("Age: \(person.job)")
                    }.padding()
                }
            }
            Button("Click") {
                // In this part i am tryn to use.
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

This is my SwiftUI view but I can't understand which section I am gonna use sorry about that. Should I add all class and structs in this view ?
Sorry about that I am kind of new on swift and can't find good resource anywhere. I checked documentations too but I understand nothing.

CodePudding user response:

here is my test code that shows doing model.people[0].myPerson.toggle() in the Button does work. I have made some minor mods and added some comments to the code.

I suggest again, read the very basics of Swift, in particular the array section at: https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html. Without understanding these very basic concepts you will keep struggling to code your App.

Note, there is probably no need for the myPeople array in your Model, but if that's what you want to have.

struct Person: Identifiable{
    let id = UUID()
    var name: String
    var age: Int
    var job: String
    var myPerson: Bool
}

class Model: ObservableObject {
    @Published var people: [Person] = []
    @Published var myPeople: [Person] = []
    
    init(){
        addPeople()
    }

    // completely useless
    func addPeople(){
        people = peopleData
        myPeople = peopleData.filter { $0.myPerson }
    }
    
    // here inside the class and using `Person` not `person`
    var peopleData = [
        Person(name: "Bob", age: 22, job: "Student", myPerson: false),
        Person(name: "John", age: 26, job: "Chef", myPerson: false)
    ]
}

struct ContentView: View {
    
    @StateObject var model = Model()
    
    var body: some View {
        
        VStack {
            VStack {
                // this `myPeople` array is empty at first, nothing is displayed
                ForEach(model.myPeople) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)").foregroundColor(.blue)
                        Text("Age: \(person.age)").foregroundColor(.blue)
                        Text("Job: \(person.job)").foregroundColor(.blue)
                        Text("myPerson: "   String(person.myPerson)).foregroundColor(.blue)
                    }.padding()
                }
            }
            VStack {
                // this `people` array has two items in it
                ForEach(model.people) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)").foregroundColor(.red)
                        Text("Age: \(person.age)").foregroundColor(.red)
                        Text("Job: \(person.job)").foregroundColor(.red)
                        Text("myPerson: "   String(person.myPerson)).foregroundColor(.red)
                    }.padding()
                }
            }
            Button("Click") {
                print("\n--> before name: \(model.people[0].name) ")
                print("--> before myPerson: \(model.people[0].myPerson) ")
                model.people[0].name = "Franz"
                model.people[0].myPerson.toggle()
                print("\n--> after name: \(model.people[0].name) ")
                print("--> after myPerson: \(model.people[0].myPerson) ")

                // update the myPeople array (the blue items)
                model.myPeople = model.people.filter { $0.myPerson }
            }
        }
    }
}

Alternatively, you could use this code using only one array of people: [Person]:

class Model: ObservableObject {
    @Published var people: [Person] = []

    init(){
        addPeople()
    }

    func addPeople() {
        people = peopleData
    }
    
    // here inside the class and using `Person` not `person`
    var peopleData = [
        Person(name: "Bob", age: 22, job: "Student", myPerson: false),
        Person(name: "John", age: 26, job: "Chef", myPerson: false)
    ]
}

struct ContentView: View {
    @StateObject var model = Model()
    
    var body: some View {
        VStack {
            VStack {
                // here filter on myPerson=true
                ForEach(model.people.filter { $0.myPerson }) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)").foregroundColor(.blue)
                        Text("Age: \(person.age)").foregroundColor(.blue)
                        Text("Job: \(person.job)").foregroundColor(.blue)
                        Text("myPerson: "   String(person.myPerson)).foregroundColor(.blue)
                    }.padding()
                }
            }
            VStack {
                // here filter on myPerson=false
                ForEach(model.people.filter { !$0.myPerson }) { person in
                    VStack(alignment: .leading){
                        Text("Name: \(person.name)").foregroundColor(.red)
                        Text("Age: \(person.age)").foregroundColor(.red)
                        Text("Job: \(person.job)").foregroundColor(.red)
                        Text("myPerson: "   String(person.myPerson)).foregroundColor(.red)
                    }.padding()
                }
            }
            Button("Click") {
                model.people[0].name = "Franz"
                model.people[0].myPerson.toggle()
            }
        }
    }
}
  • Related