I’m trying to implement a carousal such that the central item is larger than the items on the sides. I’ve added a scaleEffect but I can’t figure out how to detect & update the items such that the scaleEffect takes effect?
struct ContentView: View {
@State private var currentIndex: Int = 0
private let images = ["img","img","img","img","img","img"]
var body: some View {
VStack(spacing: 0) {
ScrollView(.horizontal) {
LazyHStack(spacing: 0) {
ForEach(0..<images.count, id: \.self) { index in
Image(images[index])
.resizable()
.scaledToFill()
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.padding(.horizontal, 25)
.scaleEffect(currentIndex == index ? 1 : 0.8)
.animation(.easeIn, value: currentIndex)
.containerRelativeFrame(.horizontal)
.id(index)
}
}
.scrollTargetLayout()
}
.frame(height: 350)
.padding(.vertical)
.scrollIndicators(.never)
.scrollTargetBehavior(.viewAligned)
.safeAreaPadding(.horizontal, 70)
.safeAreaPadding(.vertical, 10)
Spacer()
}
}
}
>Solution :
Apply the scrollTransition modifier to the Image:
.scrollTransition { content, phase in
content
.scaleEffect(phase.isIdentity ? 1 : 0.8)
}
Instead of managing your own currentIndex state, this modifier gives you a phase, and you can decide the scale based on that. It also animates the effect automatically.
By checking phase == .topLeading/phase == .bottomTrailing separately, you can also have different effects depending on which side of the scroll view the image is at.