Reputation: 1185
I want to build a custom List which allows the User to select one entry leading to a Picker to show up.
Because the Picker takes up more space than the default entry, the other elements in the List should move accordingly. I used a ForEach loop and a VStack to achieve that goal.
However, sometimes the onTapGesture doesn't do anything. Debugging my code, I found out that the onTapGesture works like it should - but the index of the tapped entry is wrong. See the GIF below: Clicking on the "1" and "2" should lead to an output of index "1" and "2" but that's not the case. Does anybody know why? Thanks a lot!
struct ContentView: View {
@State var timeList: [Int] = [1, 2, 3]
@State var selectedElement = 0
@State var sec = 0
var body: some View {
ScrollView(){
VStack{
ForEach(timeList, id: \.self){ elem in
ZStack{
VStack{
ZStack{
Rectangle()
.cornerRadius(elem == self.selectedElement ? 20 : 50)
.frame(height: elem == self.selectedElement ? 120 : 40)
.foregroundColor(Color.gray.opacity(0.3))
.padding()
Text("\(elem)").opacity(elem == self.selectedElement ? 0 : 1)
}
}
if(elem == self.selectedElement){
HStack{
Spacer()
Picker(selection: self.$sec, label: Text("")){
Text("abc")
}
Spacer()
}
}
}
.frame(height: elem == self.selectedElement ? 100 : 30)
.padding()
.onTapGesture {
withAnimation(.spring()){
self.selectedElement = elem
print(self.selectedElement)
}
}
}
}
Spacer()
Button(action: {
self.timeList.append(5)
})
{
Text("add")
}
}
}
}
Upvotes: 1
Views: 274
Reputation: 257749
Everything's fine with your code, you just tapped in transparent space, which is not handled by default.
Here is fix - just made entire area hit-available (tested with Xcode 12 / iOS 14)
.contentShape(Rectangle()) // << fix !!
.onTapGesture {
withAnimation(.spring()){
// print(elem) // << here if you want
self.selectedElement = elem
}
}
Upvotes: 1