hi,
i'll offer three suggestions.
there's no need (or there may be, but not in this example) for User to be a class. make it a struct and kill the ObservableObject protocol.
struct User: Identifiable {
let id = UUID()
var name: String
init(name: String) { self.name = name }
}
treat the Users object as a viewModel, and when a change is made to a user's name, provide a method for the Users object to do that.
class Users: ObservableObject {
@Published var users: [User]
init() {
self.users = [
User(name: "John Doe"),
User(name: "Jane Doe")
]
}
func updateUsername(for user: User, to newName: String) {
if let index = users.firstIndex(where: { $0.id == user.id }) {
users[index].name = newName
}
}
}
and treat the UserDetailView to not be a live edit, but one where you have parameters users and user coming in; you offload the name you want to edit when the view comes on screen; and when you save the edit, ask the Users object to make that change for you. something like this (with the Save button now also dismissing the view).
struct UserDetail: View {
@Environment(\.presentationMode) var presentationMode
var user: User
var users: Users
@State private var username: String = ""
var body: some View {
VStack {
TextField("Enter Name", text: $username)
Button(action: {
self.users.updateUsername(for: self.user, to: self.username)
self.presentationMode.wrappedValue.dismiss()
}, label: { Text("Save") })
}
.onAppear { self.username = self.user.name }
}
}
that should do it. when the Users object updates the user's name in its array, your TestNavigationView will know about it.
hope that helps,
DMG
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: