Two different edit views in my code and one doesn't update the parent on dismiss

I have a simple app I'm working on.
There is a data model which is stored in an environment object.

The app has an array of people, and each person has an array of events associated with them.

So, I have a Person Detail view with an edit button which presents a Person Edit view via a navigation link. The edit view has a save button which updates the environment object model and dismisses the view.
This works.

On the Person Detail view there is a list of events. Tapping on an event takes you to an Event Detail view. With almost exactly the same code, there is a Edit Event Detail view that is triggered by an Edit button in the same manner as above. The model is updated in the same way and the view is dismissed. B

Here's the pain point - when you go from a Person Edit view to Person Detail view, it updates the information on the Person Detail View.
On the Event side, after a save, the Event Detail view is not updated. You can go back up the stack and re-enter the Event Detail view and the data is updated.

Here's what's driving me insane. This is on an iOS simulator and real device.
If I try it on an iPad, same code, same views, same everything both views update correctly.

Person Detail:
Code Block
struct PersonDetailView: View {
    var person:Person
    @EnvironmentObject var model:DataStore
    @State private var selectedSection = 0
    var body: some View {

....

Code Block
NavigationLink(destination: EditPersonView(personId:person.id, person: person) ){


Person Edit:
Code Block struct EditPersonView: View {
    var personId:UUID
    @State var person:Person
    @EnvironmentObject var model:DataStore
    @Environment(\.presentationMode) var presentation
    var body: some View {

Code Block
Button(action: {
model.updatePerson(id: person.id, newLastName: person.lastName, newGivenName: person.givenName, newNickName: person.nickName, newGender: person.gender);
presentation.wrappedValue.dismiss()
}, label: {
Text("Save")
})



Event Detail:
Code Block
struct LifeEventDetailView: View {
    var lifeEvent:LifeEvent
    var person:Person
    @State var coordinates:MKCoordinateRegion
    @EnvironmentObject var model:DataStore
    var body: some View {

...
Code Block  
NavigationLink(destination: EditLifeEventView(person: person, eventId: lifeEvent.id, event: lifeEvent)){


Event Edit:
Code Block
struct EditLifeEventView: View {
    var person:Person
    var eventId:UUID
    @State var event:LifeEvent
    @EnvironmentObject var model:DataStore
    @Environment(\.presentationMode) var presentation
    


Code Block
Button("Save", action: {
model.updateLifeEvent(id: event.id, type: event.type, primaryPerson: person.id, secondaryPerson: event.secondaryPerson, date: event.date, location: event.location, notes: event.notes)
presentation.wrappedValue.dismiss()
})


Since the code for the Person view is the same as the event view, I just can't understand if the event view is wrong, how does the person view work?

How can the code work on iPad but not iPhone - with the same view code/navigation code. Am I just hitting a bug in the beta?

hi,

i don't have an opinion on simulator/iPhone/iPad differences, but it would be useful to see the definition of DataStore. is it an ObservableObject? does it actually publish changes both on updatePerson() and updateLifeEvent() ? it could be that the former does publish changes, but maybe the second does not?

it's also curious that you have @State var person:Person in the EditPersonView, but only var person:Person in the LifeEventDetailView, so that the code is not exactly the same.

finally, it might also be useful to see the Person Detail view code, from which you jump into the EditPersonView and the LifeEventDetailView, and especially how the list of events is constructed.

hope i can help out,

DMG
Second Reply Withdrawn

i had something else to add and maybe correct in my earlier reply, but once i posted it, i realized it didn't make quite as much sense as i thought. but i cannot delete what i posted. i might try later.
Yes - the data store is an observable object:

Code Block
class DataStore:ObservableObject
{
    @Published var people:[Person];
    @Published var lifeEvents:[LifeEvent];
....


And the updates work in the same way:
Code Block
 func updatePerson(id:UUID, newLastName:String, newGivenName:String, newNickName:String, newGender:Gender)
    {
        let index = people.firstIndex(where: {$0.id == id})
        people[index!].lastName = newLastName;
        people[index!].givenName = newGivenName;
        people[index!].nickName = newNickName;
        people[index!].gender = newGender;
    }


The life event is exactly the same style.

hi,

sorry about my earlier attempt to post something ... i just wish you could delete these things!

your original post said that "The app has an array of people, and each person has an array of events associated with them." that doesn't seem to fit the DataStore you showed, which appears to keep independent lists of people and life events.

later you say that "On the Person Detail view there is a list of events. Tapping on an event takes you to an Event Detail view."

that's why i asked to see the list code in PersonDetailView. how do you associate life events to a particular person? is there a DataSource method to filter out events for a given person and is that used to build out the list in PersonDetailView?

so, it would be helpful if we saw the definition of Person and LifeEvent, whether each is a struct or a class, the relevant view code in PersonDetailView for the list, and the definition of the DataStore method updateLifeEvent(id: event.id, ....

i am truly interested in helping on this, since i have constantly run into view updates as you describe. even just yesterday, an app i was using just stopped doing all the visual updates in a situation like yours that had been working fine. it turned out that i had cleaned up some code and, for some reason, labeled a variable as @State when it was not labeled that way before. even though it seemed the logical thing to do, it turned out to be exactly the problem.

hope that helps,
DMG
Two different edit views in my code and one doesn't update the parent on dismiss
 
 
Q