Post

Replies

Boosts

Views

Created

Updating item in nested observed array with swiftUI
I have an observed object called event view model, which handles the logic for all events. Each event has some todo items which need to be done and should be toggle-able. I have tried to solve this problem however, my code looks terrible and would be very bad to maintain later on. swift /// Models struct TodoPG: Identifiable { var id = UUID().uuidString var title: String var done = false } struct EventPG: Identifiable, Equatable { var id = UUID().uuidString var title: String var todos: [TodoPG] var totalTodos: Int { return todos.filter{ !$0.done }.count } static func == (lhs: EventPG, rhs: EventPG) - Bool { return lhs.id == rhs.id } } swift /// View Models class EventsViewModelPG: ObservableObject { @Published var events: [EventPG] init() { let todos = [TodoPG(title: "todo item one", done: true), TodoPG(title: "todo item two"), TodoPG(title: "todo item three")] self.events = [EventPG(title: "event one", todos: todos), EventPG(title: "event two", todos: todos)] } func update(event: EventPG) { print("update") self.events = events.map{ ($0.id == event.id) ? event : $0} } func addEvent(event: EventPG) { self.events.append(event) } } And lastly my horrible looking code swift /// Views struct EventViewPG: View { @ObservedObject var eventsVM: EventsViewModelPG var body: some View { VStack (alignment: .leading) { List(eventsVM.events.indices) { eventIndex in VStack { Text(eventsVM.events[eventIndex].title) .font(.title) Text("items todo: \(eventsVM.events[eventIndex].totalTodos)") .font(.title3) ForEach(eventsVM.events[eventIndex].todos.indices) { todoIndex in HStack { Image(systemName: eventsVM.events[eventIndex].todos[todoIndex].done ? "checkmark.square" : "square") .resizable() .frame(width: 24, height: 24) .foregroundColor(eventsVM.events[eventIndex].todos[todoIndex].done ? .blue : .gray) .font(.system(size: 20, weight: .regular, design: .default)) Text(eventsVM.events[eventIndex].todos[todoIndex].title) Spacer() }.padding(5.0) .onTapGesture(perform: { eventsVM.events[eventIndex].todos[todoIndex].done.toggle() }) } } } } } } Is there a simpler way to eliminate the keeping track of all the indices. Thank you in advanced. I've added a gist of the full code here: https://gist.github.com/yustarandomname/07fe9816523edd94382844787971e626
3
0
2.5k
Feb ’21