SwiftUI水平ScrollView滚动时如何实现视图居中对齐?
SwiftUI水平ScrollView滚动结束后视图居中对齐方案
你的场景是:水平ScrollView内的图片高度一致、宽度可变,当前使用.scrollTargetBehavior(.viewAligned)时滚动默认对齐leading边缘,但点击视图能通过.scrollPosition(id: $detailScrollPosition, anchor: .center)触发居中对齐,需要实现手动滚动结束后也自动让视图居中。
解决方法
通过自定义ScrollTargetBehavior,修改滚动结束时的目标偏移量,让当前视图自动居中;同时保留点击触发居中的逻辑。
修改后的完整代码
import SwiftUI import Kingfisher struct TopPostMediaView: View { @State var detailScrollPosition: UUID? = nil var body: some View { ScrollView { VStack(alignment: .leading, spacing: 10) { GeometryReader { proxy in let containerSize = proxy.size ScrollView(.horizontal) { HStack(spacing: 10) { ForEach(mynewtemp) { pic in KFImage(URL(string: pic.photo)) .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: containerSize.width) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(Color.gray.opacity(0.4), lineWidth: 1.0) ) .clipShape(RoundedRectangle(cornerRadius: 10)) .contentShape(RoundedRectangle(cornerRadius: 10)) .onTapGesture { withAnimation(.easeInOut(duration: 0.15)) { detailScrollPosition = pic.id } } .frame(maxWidth: containerSize.width, maxHeight: containerSize.height) } } .scrollTargetLayout() } .scrollPosition(id: $detailScrollPosition, anchor: .center) .scrollIndicators(.hidden) .scrollTargetBehavior(CenterAlignedScrollBehavior(containerWidth: containerSize.width)) .scrollClipDisabled() } .frame(height: 250) } } } } // 自定义滚动目标行为:让视图滚动结束后居中 struct CenterAlignedScrollBehavior: ScrollTargetBehavior { let containerWidth: CGFloat func updateTarget(_ target: inout ScrollTarget, context: ScrollTargetContext) { // 计算让视图居中的偏移量:视图中点 - ScrollView容器的一半宽度 target.contentOffset.x = target.rect.midX - containerWidth / 2 } } #Preview { TopPostMediaView() } let mynewtemp: [tempStruct] = [ tempStruct(id: UUID(), photo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRmCy16nhIbV3pI1qLYHMJKwbH2458oiC9EmA&s"), tempStruct(id: UUID(), photo: "https://th.bing.com/th/id/OIG2.9O4YqGf98tiYzjKDvg7L"), tempStruct(id: UUID(), photo: "https://th.bing.com/th/id/OIG2.9O4YqGf98tiYzjKDvg7L") ] struct tempStruct: Identifiable, Hashable { var id: UUID var photo: String }
关键说明
- 自定义
ScrollTargetBehavior:通过updateTarget方法修改滚动结束后的目标偏移量,让视图的中点与ScrollView容器的中点对齐,实现居中效果。 - 保留原点击逻辑:点击视图时仍通过修改
detailScrollPosition触发带动画的居中滚动,与滚动行为保持一致。 - 简化视图层级:移除了多余的
LazyHStack,直接让图片作为HStack的子视图,减少不必要的层级嵌套。
内容的提问来源于stack exchange,提问作者Ahmed Zaidan
相关产品推荐
相关产品推荐

