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

SwiftUI:如何使用ScrollViewReader将列表滚动到指定分区与列表项

解决ScrollViewReader无法滚动到指定分区列表项的问题

这个坑我之前踩过!问题出在列表项的id不唯一上:你用\.self作为ForEach的标识,但不同月份里的日期数字是重复的(比如一月的9号和六月的9号id都是9),scrollTo只会找到第一个匹配的id,自然就只会定位到一月的元素了。

解决方案:给每个列表项生成唯一标识符

我们需要给每个日期创建独一无二的id,最简单的方式是用**(月份索引, 日期)**的元组作为标识,这样每个日期的id都是唯一的(比如六月的9号就是(5, 9),因为六月是第6个月份,对应数组索引5)。

修改后的完整代码示例

let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 ,31]
// 定义月份名称数组,方便循环生成Section,避免重复写代码
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

ScrollViewReader { scroll in
    List {
        ForEach(0..<12, id: \.self) { sectionIndex in
            Section(monthNames[sectionIndex]) {
                ForEach(0..<daysInMonth[sectionIndex], id: \.self) { day in
                    // 给每个CalendarRow绑定唯一的id:(月份索引, 日期)
                    CalendarRow(calendar: fetchCalendarData(section: sectionIndex, index: day))
                        .id((section: sectionIndex, day: day))
                }
            }
        }
    }
}
.onAppear {
    withAnimation {
        // 滚动到六月(sectionIndex=5)的第9天,传入对应的唯一id
        scroll.scrollTo((section: 5, day: 9), anchor: .center)
    }
}

关键说明

  1. 唯一id的绑定:通过给CalendarRow添加.id((section: sectionIndex, day: day)),让每个列表项拥有独一无二的标识,彻底解决id重复的问题。
  2. 简化Section生成:用循环批量生成12个月份的Section,避免手动重复写12次代码,后续维护更方便。
  3. scrollTo的参数匹配:调用scrollTo时,必须传入和列表项完全一致的元组类型——比如要定位到六月9号,就传入(section: 5, day: 9)(注意月份索引从0开始,六月是第6个月份,所以索引是5)。

这样修改后,你就能精准滚动到任意月份的任意日期啦!

内容的提问来源于stack exchange,提问作者Mc.Lover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:52:40