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

使用scrollPosition(id:anchor:)锚定中心时选中项错误求助

SwiftUI横向滚动视图正确获取居中项的技巧

你遇到的问题核心在于scrollPosition(id:anchor:)的锚点计算是基于滚动视图的可滚动内容区域,直接给ScrollView添加contentMargins会让容器边距干扰锚点判定逻辑,导致选中项和视觉中心不匹配。

以下是修复后的实现方案:

修复步骤与代码示例

  1. 将contentMargins移至LazyHStack内部,确保滚动内容范围包含边距,让锚点计算基于正确的内容区域。
  2. 添加scrollTargetBehavior(.viewAligned),确保滚动停止时视图严格对齐到目标位置,避免半选中情况。
struct ScrollPositionSample: View {
    let words = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod".components(separatedBy: " ")
    @State private var selection: String? = "Lorem"
    
    var body: some View {
        VStack {
            if let selection {
                Text("Selected: \(selection)")
                    .font(.title3)
            }

            ScrollView(.horizontal) {
                LazyHStack {
                    ForEach(words, id: \.self) { word in
                        Text(word)
                            .font(.title2)
                            .padding()
                            .background(.teal, in: RoundedRectangle(cornerRadius: 5.0))
                    }
                }
                // 将边距移到内容内部,让滚动区域包含这些边距
                .contentMargins(.leading, 100)
                .contentMargins(.trailing, 40)
                .scrollTargetLayout()
                .frame(maxHeight: 125)
            }
            .scrollPosition(id: $selection, anchor: .center)
            // 添加视图对齐的滚动目标行为
            .scrollTargetBehavior(.viewAligned)
            .overlay {
                Color.red.frame(width: 2)
            }
        }
    }
}

额外优化建议

如果滚动项宽度差异较大,可以通过两种方式进一步确保居中准确性:

  • 给每个项设置固定宽度:
Text(word)
    .font(.title2)
    .frame(width: 150) // 统一固定宽度
    .padding()
    .background(.teal, in: RoundedRectangle(cornerRadius: 5.0))
  • 启用分页模式滚动:
// 替换视图对齐为分页模式
.scrollTargetBehavior(.paging)

内容的提问来源于stack exchange,提问作者RL2000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:12:13