0

I have a CoordinateList view that shows a list of CoordinateRow views that have been entered, and are editable in place (in the list view). To add a new point to the list, the user presses a button at the bottom of the list, and it adds a row (without going to another screen). How do I make it update the view to show this new entry? I have tried wrapping the append function of the list of coordinates with a function so that I can call objectWillChange.send() when adding to the list, but it doesn't seem to do anything.

I guess I don't have enough reputation to upload an image, but here's an image:

demo

import SwiftUI

class LocationTime : ObservableObject {
    @Published var lat: String = "0.0"
    @Published var lon: String = "0.0"
    @Published var timestamp: String =  "SomeDateTime"
}

class ModelData: ObservableObject {
    @Published var positionCoords = [LocationTime]()
    func appendPosition(_ loc: LocationTime) {
        objectWillChange.send()
        positionCoords.append(loc)
    }
}

struct CoordinateRow: View {
    @EnvironmentObject var modelData: ModelData
    var pointIndex : Int
    var body: some View {
        HStack {
            Text("Lon: ")
            TextField("40",text:$modelData.positionCoords[pointIndex].lon)
            Text("Lat: ")
            TextField("",text:$modelData.positionCoords[pointIndex].lat)
            Text("Time: ")
            TextField("time",text:$modelData.positionCoords[pointIndex].timestamp)
        }.padding()
        .overlay(RoundedRectangle(cornerRadius:16)
                    .stroke(Color.blue,lineWidth:4.0))
    }
}

struct CoordinateList: View {
    @EnvironmentObject var modelData : ModelData
    
    var body: some View {
        VStack{
            Text("Location Log")
                .font(.largeTitle).padding()
            List{
            ForEach(modelData.positionCoords.indices){
                CoordinateRow(pointIndex: $0).environmentObject(modelData)
            }
            }
            Button(action:{
                modelData.appendPosition(LocationTime())
                print(modelData.positionCoords.count)
            }){
                Image(systemName: "plus.circle")
                    .imageScale(.large)
                    .scaleEffect(2.0)
                    .padding()
            }
            
            
            Spacer()
        }
        
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
Sean Ogden
  • 158
  • 1
  • 7

1 Answers1

0

You need identify records in ForEach

ForEach(modelData.positionCoords.indices, id: \.self){     // << here !!
    CoordinateRow(pointIndex: $0).environmentObject(modelData)
}

and by the way, remove objectWillChange.send()

    func appendPosition(_ loc: LocationTime) {
//        objectWillChange.send()      // << called automatically for @Published
        positionCoords.append(loc)
    }
Asperi
  • 228,894
  • 20
  • 464
  • 690