This is TaskModel
import Foundation
import SwiftUI
struct TaskModel: Identifiable, Codable {
var id = UUID().uuidString
var title : String
var selectedColor : Color
var remindedTime : Int
var taskDate : Date
}
This is ViewModel I tried
import Foundation
import SwiftUI
class CalendarViewModel : ObservableObject {
@Published var tasks : [TaskModel] = []
@Published var currentMonth : Int = 0
func addTask(title : String, selectedColor : Color, reminderTime : Int, taskDate : Date) {
let newTask = TaskModel(title: title, selectedColor: selectedColor, remindedTime: reminderTime * 60, taskDate: taskDate)
tasks.append(newTask)
}
func deleteTask(task : TaskModel) {
if let index = tasks.firstIndex(where: {$0.id == task.id }) {
tasks.remove(at: index)
}
}
This is the ForEach I tried to delete row
VStack {
ForEach(vm.tasks.filter({vm.isSameDay(date1: $0.taskDate, date2: currentDate)})) { task in
TaskRowView(task: task)
.actionSheet(isPresented: $isShowActionSheet) {
ActionSheet(title: Text("Settings"), message: Text("Press the button that what you want to do 😀"), buttons: [
.cancel(), .destructive(Text("Delete"), action: {
vm.deleteTask(task: task)
}), .default(Text("Edit"), action: {
})
])
}
}
.onLongPressGesture {
isShowActionSheet.toggle()
}
}
And this is the picture of my app View.
The weird thing is when I tried to delete second row of the List, The first row is deleted and second is left.
But, I can't find my miss point.
The simplest way to implement this is with an optional selection variable and a custom binding for the .actionSheet()
. Please see the code below. I commented the important parts. I also changed your code to a Minimal Reproducible Example (MRE) for demonstration purposes.
struct ContentView: View {
@State var tasks = Array(1...20).map( { TaskModel(title: "Task \($0)") })
// This is your optional selection variable
@State var selectedRow: TaskModel?
var body: some View {
VStack {
ForEach(tasks) { task in
Text(task.title)
// put the .onLongPressGesture() on the row itself
.onLongPressGesture {
// set selectedRow to the task
selectedRow = task
}
// This creates a custom binding
.actionSheet(isPresented: Binding<Bool>(
// the get returns the Bool that is the comparison of selectedRow and task
// if they are equal, the .actionSheet() fires
get: { selectedRow == task },
// when done, .actionSheet() sets the Binding<Bool> to false, but we intercept that
// and use it to set the selectedRow back to nil
set: { if !$0 {
selectedRow = nil
}})) {
ActionSheet(
title: Text("Settings"),
// added task.title to prove the correct row is in the ActionSheet
message: Text("Press the button for \(task.title)"),
buttons: [
.cancel(),
.destructive(Text("Delete"), action: {}),
.default(Text("Edit"), action: {})
]
)
}
}
}
}
}