First, your [ItemDataModel]
array should be moved outside the body, so it's not recreated every time:
struct ListView: View {
@State var selected = Set<Int>()
let items = (1...10).map(ItemDataModel.init) // move outside the `body`
var body: some View {
VStack {
Text(String(describing: selected))
List(items) { item in
ListItemView(dataModel: item)
.onTapGesture { if !(selected.remove(item.id) != .none) { selected.insert(item.id) }}
}
}
}
}
Then, make sure that the Toggle
in your ListItemView
doesn't take all the space (that's the default behaviour) and attach onTapGesture
to override the parent's gesture:
struct ListItemView: View {
@ObservedObject var dataModel: ItemDataModel
var body: some View {
HStack {
Text(dataModel.title)
// Text("toggle") // if necessary add Toggle's label as `Text`
Spacer()
Toggle("", isOn: $dataModel.isOn) // use another initialiser
.fixedSize() // limit Toggle's width
.background(Color.red) // debug-only, to see the real frame
.onTapGesture {} // override tap gestures
}
.contentShape(Rectangle()) // make empty space *clickable*
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…