I'm try to make a ToDoApp using TCA and CoreData. When the user tap on a cell I would to change the complete attribute and change the value of the checkbox of the task cell.
struct MainViewModel: ReducerProtocol {
let loadElements: () -> [Tasks]
struct State: Equatable {
var showForm: Bool = false
var buttonIcon: String {
showForm ? "minus" : "plus"
}
var tasks: [Tasks] = []
}
enum Action: Equatable {
case showHideForm
case loadElement
case addElement(String)
case toggleCompleted(Tasks)
}
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case .showHideForm:
state.showForm.toggle()
return .none
case .loadElement:
state.tasks = loadElements()
return .none
case .addElement(let name):
StorageContainer.shared.addElement(event: name)
let effects: [EffectTask<MainViewModel.Action>] = [EffectTask(value: .showHideForm), EffectTask(value: .loadElement)]
return .concatenate(effects)
case .toggleCompleted(let task):
StorageContainer.shared.update(task: task)
return EffectTask(value: .loadElement)
}
}
}
In the view I call the update action when the user tap on the cell
ForEach(vm.tasks, id: \.self) { task in
TaskCell(task: task)
.onTapGesture {
vm.send(.toggleCompleted(task), animation: .easeInOut)
}
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
}
Here you can see how I update the entity in core data
func update(task: Tasks) {
task.completed.toggle()
save()
}
func save() {
try? container.viewContext.save()
}