Search code examples
iosarraysswiftswiftuiproperty-wrapper

SwiftUI code assigns one object data to all other objects in array?


I'm trying to a build a notecard app, and currently I'm working on screen where the user can enter notecards. Everything works fine, except when I type in my term and definition for one notecard, it updates all other notecards so that they have the same term and definition. Thank you so much for any help, it is appreciated!:)

Here is a preview of my code

import SwiftUI

struct Notecard: Identifiable
{
    let id = UUID()
    let term2: String
    let def2: String
}
class Notecards: ObservableObject
{
   @Published var Notecardsarray = [Notecard]() //stores an array of the notecard items into a single object
}
struct ContentView: View{
    @ObservedObject var notecardobject = Notecards()
    @State private var term = "dfs"
    @State private var def = "df"

    var body: some View {
        NavigationView{
        List{
            ForEach(notecardobject.Notecardsarray){item in
                HStack{
                    TextField("enter term", text: self.$term)
                    TextField("enter definition", text: self.$def)
                }
            }
            .onDelete(perform: removeItems)
        }
    .navigationBarTitle("Notecards")
      .navigationBarItems(trailing:
          Button(action: {
            let newnotecard = Notecard(term2: self.term, def2: self.def)
              self.notecardobject.Notecardsarray.append(newnotecard)
          }) {
              Image(systemName: "plus")
          }
      )
        }

    }
   func removeItems(at offsets: IndexSet) {
       notecardobject.Notecardsarray.remove(atOffsets: offsets)
   }
}
//this will not actually be part of the app that goes to app store
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Solution

  • When you require a Binding in a ForEach loop, you need to loop through the indices rather than the elements.

    Updated Notecard by making term2 and def2 mutable.

    struct Notecard: Identifiable {
        let id = UUID()
        var term2: String
        var def2: String
    }
    

    Updated ContentView by changing the ForEach loop.

    ForEach(notecardobject.Notecardsarray.indices, id: \.self){ index in
        HStack{
            TextField("enter term", text: self.$notecardobject.Notecardsarray[index].term2)
            TextField("enter definition", text: self.$notecardobject.Notecardsarray[index].def2)
        }
    }