I have a simple project where I have a UUID string followed by a tap button as shown below. If one taps the Add me, the app will list a new instance of a View (KeywordRow).
The following is what I have.
import SwiftUI
struct ContentView: View {
@ObservedObject var monster: Monster
var body: some View {
VStack {
Button {
monster.items.append(Keyword())
} label: {
Text("Add me!")
}.padding(.vertical, 10.0)
ForEach($monster.items) { item in
KeywordRow(id: item.id)
}
}
}
}
// MARK: - ObservableObject
class Monster: ObservableObject {
@Published var items = [Keyword]()
}
// MARK: - Keyword
struct Keyword: Identifiable {
var id = UUID()
}
struct KeywordRow: View {
@Binding var id: UUID
var body: some View {
VStack {
HStack {
Text("ID: \(id)")
Button {
/* ------ Delete ------ */
} label: {
Text("Delete")
}
}
}
}
}
My question is how I can let the app delete the corresponding instance when I tap the Delete button? I have an ObservedObject variable, which I haven't used. Thanks.
Use environment object, and that works:
struct ContentView: View {
@ObservedObject var monster: Monster
var body: some View {
VStack {
Button {
monster.items.append(Keyword())
} label: {
Text("Add me!")
}.padding(.vertical, 10.0)
ForEach($monster.items) { item in
KeywordRow(id: item.id).environmentObject(monster) // <<-- NEW and essential
}
}
}
}
// MARK: - ObservableObject
class Monster: ObservableObject {
@Published var items = [Keyword] ()
}
// MARK: - Keyword
struct Keyword: Identifiable {
var id = UUID()
}
struct KeywordRow: View {
@Binding var id: UUID
@EnvironmentObject var monster: Monster // <<-- NEW
var body: some View {
VStack {
HStack {
Text("ID: \(id)")
Button {
monster.items.removeAll(where: { $0.id == id} ) /* ------ Delete ------ */ // <<-- NEW
} label: {
Text("Delete")
}
}
}
}
}
And in SceneDelegate,
let contentView = ContentView(monster: Monster()) // <<-- Pass parameter