I have a quite few reusable viewmodifiers in my projects, but I have never been able to make one that accepts any object instead of a specific object.
Fx. in below viewmodifier, how would I make it accept any object instead of just "StopContent" so I didn't have to write a new viewModifier each time I wanted to use it on a new object?
struct DragToDeleteContent: ViewModifier {
let stopContent:StopContent
@Binding var contentArray: [StopContent]
@State private var deleted:Bool = false
func body(content: Content) -> some View {
return content
.dragToDelete(deleted: $deleted)
.onChange(of: deleted, perform: { deleted in
if deleted { delete() }
})
}
func delete() {
if let arrayIndex = contentArray.firstIndex(of: stopContent) {
contentArray.remove(at: arrayIndex)
}
}
}
Every model confirms with Identifiable
protocol so you can make it generic by Identifiable.
here is the possible solution
struct DragToDeleteContent<T: Identifiable>: ViewModifier {
let stopContent: T
@Binding var contentArray: [T]
@State private var deleted:Bool = false
func body(content: Content) -> some View {
return content
.dragToDelete(deleted: $deleted)
.onChange(of: deleted, perform: { deleted in
if deleted { delete() }
})
}
func delete() {
if let arrayIndex = contentArray.firstIndex(where: {$0.id == stopContent.id}) {
contentArray.remove(at: arrayIndex)
}
}
}
Data Model
struct TestModel: Identifiable {
var id = UUID()
var name: String
}
Usage
}.modifier(DragToDeleteContent(stopContent: TestModel(name: "Abc"), contentArray: .constant([.init(name: "Xyz"), .init(name: "opq")]))) // I used .constant for the demo purpose. Bind you Identifiable array here.