I have a horizontal ScrollView, which iterates an array of numbers and for each number a red card is created. When you press a card, that red card expands and only that one is shown. The thing is that when I want to stop expanding the view and go back to the previous state, the whole view is rendered again, returning the scrollview to the beginning (I don't know if I explained myself well, so I'll put an example gif). What I would like to see is keep the position of the element that was selected and not return to the beginning of the ScrollView.
struct TestView: View {
@State private var items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
@State private var isAnimationActive = false
@State private var selectedItem = ""
@Namespace private var animation
var body: some View {
ZStack {
if !isAnimationActive {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(items, id: \.self) { item in
ZStack {
RoundedRectangle(cornerRadius: 30, style: .continuous)
.fill(Color.red)
.matchedGeometryEffect(id: "card\(item.description)", in: animation)
.frame(width: 250, height: 250)
if selectedItem == item.description && isAnimationActive {
Rectangle()
.fill(.green)
} else {
Text(item.description)
.foregroundColor(.white)
.matchedGeometryEffect(id: "text\(item.description)", in: animation)
}
}
.onTapGesture {
withAnimation(.easeOut(duration: 0.3)) {
isAnimationActive = true
selectedItem = item.description
}
}
}
}
.padding(.leading, 20)
}
}
if isAnimationActive {
ZStack {
RoundedRectangle(cornerRadius: 30, style: .continuous)
.fill(Color.red)
.matchedGeometryEffect(id: "card\(selectedItem.description)", in: animation)
.frame(width: 300, height: 400)
Text(selectedItem)
.foregroundColor(.white)
.matchedGeometryEffect(id: "text\(selectedItem.description)", in: animation)
}
.transition(.offset(x: 1, y: 1))
.onTapGesture {
withAnimation(.easeOut(duration: 0.3)) {
isAnimationActive = false
}
}
}
}
}
}