I am experiencing some very odd behavior from a Horizontal ScrollView, it seems as if the clickable frame of the cells are offset. For example, if you click on left half of the first cell it will register the click for the first cell, but if you click the right half of the first cell it will register a click on the second cell. I'm not sure why this is happening.
I've included the code below, you can copy and paste this code into a playground to reproduce the issue. Any ideas here?
struct TestView: View {
var image: String
var body: some View {
ZStack {
Image(systemName: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 104, height: 168)
.cornerRadius(8)
.clipped()
VStack {
Spacer()
Text("Testing")
.foregroundColor(Color.white)
.frame(alignment: .leading)
.padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
.shadow(radius: 5)
Text("1:40")
.foregroundColor(Color.white)
.frame(alignment: .leading)
.padding(EdgeInsets(top: 3, leading: 10, bottom: 10, trailing: 10))
.shadow(radius: 5)
}
.frame(width: 104, height: 168)
}
}
}
struct TestViewCollection: View {
var collection = ["tv", "faxmachine", "printer"]
var body: some View {
ScrollView {
HStack {
ForEach(collection, id: \.self) { image in
TestView(image: image)
.onTapGesture {
print(image)
}
}
}
}
}
}
PlaygroundPage.current.setLiveView(TestViewCollection())
The issue is that your images are not the same aspect ratio as the frame you have put them in, so they are overflowing the frame. The solution is pretty simple. Instead of using
.clipped()
which just clips what you can see, use.contentShape()
which will will provide an area that the.tapGesture()
will use as its tappable area. Like this: