如何在SwiftUI ScrollView中实现居中项缩放效果?
实现居中放大的轮播组件解决方案
你的核心问题是currentIndex状态没有和滚动视图的实际滚动位置绑定,导致滚动时无法自动更新索引,scaleEffect也就无法触发缩放变化。下面是修正后的实现代码和关键说明:
修正后的完整代码
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(.easeInOut(duration: 0.3), value: currentIndex) .containerRelativeFrame(.horizontal) .id(index) } } .scrollTargetLayout() } .frame(height: 350) .padding(.vertical) .scrollIndicators(.never) .scrollTargetBehavior(.viewAligned) .safeAreaPadding(.horizontal, 70) .safeAreaPadding(.vertical, 10) // 监听滚动目标变化,实时更新当前索引 .onScrollTargetChange { context in guard let targetIndex = context.targets.first?.index else { return } currentIndex = targetIndex } Spacer() } } }
关键修改说明
- 绑定滚动索引:新增
onScrollTargetChange回调,在滚动视图的目标项切换时,从context中获取当前居中项目的索引,赋值给currentIndex,让缩放效果能随滚动实时触发。 - 优化动画体验:将动画从
.easeIn改为.easeInOut(duration: 0.3),让缩放过渡更自然,你可以根据需求调整动画时长。 - 保持布局对齐:
.viewAligned的滚动目标行为配合containerRelativeFrame(.horizontal),确保每个项目滚动后都能精准居中,保证缩放效果的触发时机准确。
内容的提问来源于stack exchange,提问作者batman
相关产品推荐
相关产品推荐

