You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:12:46