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

SwiftUI中ScrollViewReader滚动至Section Header带内边距的问题

解决SwiftUI中ScrollViewReader滚动Section Header被截断的问题

问题原因

你当前把id绑定在Section内部的Text组件上,而List的Section头部本身带有容器内边距,滚动时会将Text的顶部对齐到滚动视图顶端,导致Section Header的容器内边距部分被截断。另外如果日期包含时间组件,可能会出现scrollTo目标ID不匹配的情况。

修复方案

  1. 将ID绑定到Section本身:让ScrollViewReader直接定位整个Section,而非内部的Text,这样会自动包含Section头部的内边距,避免截断。
  2. 日期归一化:将日期统一转换为当天零点,避免因时间组件差异导致ID匹配失败。

修改后的完整代码

ScrollViewReader { proxy in
    List(selection: $selectedFlights) {
        ForEach(flightStore.flightsGroupedByDate.prefix(sectionsLoaded), id: \.date) { groupedFlights in
            // 把ID从header的Text移到Section上
            Section(header: Text("\(groupedFlights.date.abbreviatedOmitted)")
                .foregroundStyle(Color.primary)
                .fontWeight(.heavy)
            ) {
                ForEach(groupedFlights.flights, id: \.id) { flight in
                    ZStack {
                        NavigationLink(value: flight) { EmptyView() }.opacity(0)
                        FlightCell(flight: flight)
                            .listRowInsets(EdgeInsets(top: 5, leading: 0, bottom: 5, trailing: 0))
                            .swipeActions(edge: .leading) { swipeActionsLeading(for: flight) }
                            .swipeActions(edge: .trailing) { swipeActionsTrailing(for: flight) }
                    }
                    .tag(flight.id)
                }
            }
            // 使用当天零点作为ID,避免时间组件干扰
            .id(Calendar.current.startOfDay(for: groupedFlights.date))
            .onAppear {
                if groupedFlights == flightStore.flightsGroupedByDate[min(sectionsLoaded-1, flightStore.flightsGroupedByDate.count-1)] {
                    loadMoreSections()
                    print("loading more sections")
                }
            }
        }
    }
    .onChange(of: calendarVM.currentDate, perform: { newDate in
        withAnimation {
            // 滚动目标也使用当天零点的日期
            proxy.scrollTo(Calendar.current.startOfDay(for: newDate), anchor: .top)
        }
    })
}

额外说明

  • 如果你的页面包含导航栏,确保List正确适配安全区域,可以添加.navigationBarTitleDisplayMode(.inline)或调整.safeAreaInset来避免头部被导航栏遮挡。
  • 确认flightStore.flightsGroupedByDate中的日期已经正确按天分组,避免同一日期出现多个Section导致滚动混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:01:34