SwiftUI中ScrollView使用.paging滚动目标行为时页面偏移问题求助
问题
在SwiftUI中使用ScrollView配合.scrollTargetBehavior(.paging)实现图片列表分页滑动时,滑动到下一页后,视图并非从下一张图片的起始位置显示,而是会包含上一张图片的末尾部分,多次滑动后上一页甚至可能占据半个屏幕。
示例代码:
import SwiftUI struct ContentView: View { var body: some View { GeometryReader { geometry in ScrollView(.horizontal) { LazyHStack { ForEach(1...10, id: \.self) { _ in Image(systemName: "rectangle.slash") .frame(width: geometry.size.width) .border(.red) } } .scrollTargetLayout() } .scrollTargetBehavior(.paging) } } } #Preview { ContentView() }
问题截图(第5页时的状态):
原因及解决办法
原因
问题出在LazyHStack的默认间距上——LazyHStack默认会给子视图之间添加8pt的间距,但你设置的子视图宽度是屏幕宽度,加上这个默认间距后,每个"页面"的实际总宽度就变成了屏幕宽度+8pt。而.scrollTargetBehavior(.paging)是基于scrollTargetLayout的整体布局来计算分页边界的,这就导致滑动时的分页位置和你预期的单张图片位置不匹配,出现上一页内容残留的情况。
解决办法
给LazyHStack添加spacing: 0,消除默认间距,让每个子视图紧密排列,这样分页的边界就会和单张图片的边界完全对齐:
修正后的代码:
import SwiftUI struct ContentView: View { var body: some View { GeometryReader { geometry in ScrollView(.horizontal) { // 添加 spacing: 0 消除默认间距 LazyHStack(spacing: 0) { ForEach(1...10, id: \.self) { _ in Image(systemName: "rectangle.slash") .frame(width: geometry.size.width) .border(.red) } } .scrollTargetLayout() } .scrollTargetBehavior(.paging) } } } #Preview { ContentView() }
内容的提问来源于stack exchange,提问作者Doraemoe
相关产品推荐
相关产品推荐

