Reputation: 1473
I have a List and items containing a Picker view (segmented control stye). I would like to handle selection and picker state separately. the picker should be disabled when list item is not selected.
The problem is:
On UIKit, Button/SegmentControl/etc... catch the 'tap' and do not pass through to TableView selection state.
struct ListView: View {
@State var selected = Set<Int>()
let items = (1...10).map { ItemDataModel(id: $0) }
var body: some View {
List(items) { item in
ListItemView(dataModel: item)
.onTapGesture { if !(selected.remove(item.id) != .none) { selected.insert(item.id) }}
}
}
}
struct ListItemView: View {
@ObservedObject var dataModel: ItemDataModel
var body: some View {
let pickerBinding = Binding<Int>(
get: { dataModel.state?.rawValue ?? -1 },
set: { dataModel.state = DataState(rawValue: $0) }
)
HStack {
Text(dataModel.title)
Spacer()
Picker("sdf", selection: pickerBinding) {
Text("State 1").tag(0)
Text("State 2").tag(1)
Text("State 3").tag(2)
}.pickerStyle(SegmentedPickerStyle())
}
}
}
enum DataState: Int {
case state1, state2, state3
}
class ItemDataModel: Hashable, Identifiable, ObservableObject {
let id: Int
let title: String
@Published var state: DataState? = .state1
init(id: Int) {
self.id = id
title = "item \(id)"
}
func hash(into hasher: inout Hasher) {
hasher.combine(title)
}
static func == (lhs: ItemDataModel, rhs: ItemDataModel) -> Bool {
return lhs.id == rhs.id
}
}
[Please try to ignore syntax errors (if exsist) and focus on the gesture issue]
Upvotes: 1
Views: 438
Reputation: 54611
A possible solution is to apply modifiers only when the Picker
is not selected:
struct ListView: View {
@State var selected = Set<Int>()
let items = (1 ... 10).map { ItemDataModel(id: $0) }
var body: some View {
List(items) { item in
if selected.contains(item.id) {
ListItemView(dataModel: item)
} else {
ListItemView(dataModel: item)
.disabled(true)
.onTapGesture {
if !(selected.remove(item.id) != .none) {
selected.insert(item.id)
}
}
}
}
}
}
Upvotes: 1