I’m trying to update the size of a ScrollView item view on tap gesture but at the moment nothing seems to happen apart from the debugger logging the following:
onChange(of: Optional<AnimalItem>) action tried to update multiple times per frame.
The code is as follows:
struct AnimalItem: Identifiable, Equatable {
private(set) var id: UUID = .init()
var text: String
var image: String
var expanded = false
}
struct AnimalItemView: View {
@State var item: AnimalItem
var body: some View {
Image(item.expanded ? item.image : item.text)
.resizable()
.scaledToFill()
.frame(width: item.expanded ? 350 : 200, height: 250)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
struct AnimalCarousalView: View {
@State var items: [AnimalItem] = [
.init(text: "A", image: "alligator"),
.init(text: "B", image: "bear"),
.init(text: "C", image: "cat")
]
@State var selectedItem: AnimalItem?
var body: some View {
ScrollView(.horizontal) {
LazyHStack(spacing: 10) {
ForEach(items, id: \.id) { item in
AnimalItemView(item: item)
.clipShape(RoundedRectangle(cornerRadius: 10))
.onTapGesture {
selectedItem = item
}
}
}
}
.frame(height: 250)
.contentShape(Rectangle())
.scrollIndicators(.hidden)
.clipped()
.onChange(of: selectedItem) { _ in
withAnimation {
selectedItem?.expanded.toggle()
}
}
}
}
What I want to achieve is for the Image in AnimalItemView to expand in width when tapped and shrink when tapped again. Also at any time, I’d like for only one scroll item view to stay expanded. Currently, nothing happens when I tap on the view. Apart from this, I also seem to require the clipShape modifier applied to the AnimalItemView as well. If I don’t, the AnimalItemView only seems to have a rounded clip for the bottom edges & the top edges appear flat. Finally, it doesn’t seem correct to have the expansion property expanded be inside AnimalItem, though I might be wrong? Any help is appreciated.




