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

SwiftUI中如何将带头部的List滚动至最顶端?

SwiftUI List 滚动至真正顶端(含Section Header)

问题原因

当前代码滚动到第一个列表项的.top锚点,仅会将该项顶部对齐List可视区域顶部,但Section Header位于列表项上方,因此无法滚动到Header完全顶在最顶端的位置。

解决方案1:给Section Header添加ID直接滚动

给Section的Header视图分配一个唯一ID,调用scrollTo时直接滚动到这个ID并设置锚点为.top,就能让Header完全顶在List的最顶端。

修改后的代码:

struct StackScrollToTopExample: View {
    private struct ExampleItem: Identifiable {
        let id = UUID()
        let title: String
    }

    private let items = [
        ExampleItem(title: "Passport"),
        ExampleItem(title: "Wallet"),
        ExampleItem(title: "Phone charger"),
        ExampleItem(title: "Headphones"),
        ExampleItem(title: "Sunglasses"),
        ExampleItem(title: "Toothbrush"),
        ExampleItem(title: "Toothpaste"),
        ExampleItem(title: "Socks"),
        ExampleItem(title: "T-shirt"),
        ExampleItem(title: "Jeans"),
        ExampleItem(title: "Jacket"),
        ExampleItem(title: "Book"),
        ExampleItem(title: "Camera"),
        ExampleItem(title: "Medication"),
        ExampleItem(title: "Water bottle"),
        ExampleItem(title: "Travel adapter"),
        ExampleItem(title: "Umbrella"),
        ExampleItem(title: "Notebook"),
        ExampleItem(title: "Snacks"),
        ExampleItem(title: "Keys"),
    ]
    // 定义Header的唯一ID
    private let sectionHeaderID = UUID()

    var body: some View {
        NavigationStack {
            ScrollViewReader { proxy in
                List {
                    Section {
                        ForEach(items) { item in
                            Text(item.title)
                                .id(item.id)
                        }
                    } header: {
                        Text("Header")
                            .id(sectionHeaderID) // 给Header绑定ID
                    }
                }
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button("Top") {
                            withAnimation {
                                proxy.scrollTo(sectionHeaderID, anchor: .top) // 滚动到Header的ID
                            }
                        }
                    }
                }
            }
        }
    }
}

解决方案2:添加隐藏的顶部锚点

如果不想修改Section Header,也可以在List最顶部添加一个高度为0的隐藏视图,给它分配ID,滚动到这个视图的.top,就能实现完全滚到顶端:

struct StackScrollToTopExample: View {
    private struct ExampleItem: Identifiable {
        let id = UUID()
        let title: String
    }

    private let items = [
        ExampleItem(title: "Passport"),
        ExampleItem(title: "Wallet"),
        ExampleItem(title: "Phone charger"),
        ExampleItem(title: "Headphones"),
        ExampleItem(title: "Sunglasses"),
        ExampleItem(title: "Toothbrush"),
        ExampleItem(title: "Toothpaste"),
        ExampleItem(title: "Socks"),
        ExampleItem(title: "T-shirt"),
        ExampleItem(title: "Jeans"),
        ExampleItem(title: "Jacket"),
        ExampleItem(title: "Book"),
        ExampleItem(title: "Camera"),
        ExampleItem(title: "Medication"),
        ExampleItem(title: "Water bottle"),
        ExampleItem(title: "Travel adapter"),
        ExampleItem(title: "Umbrella"),
        ExampleItem(title: "Notebook"),
        ExampleItem(title: "Snacks"),
        ExampleItem(title: "Keys"),
    ]
    private let topAnchorID = UUID()

    var body: some View {
        NavigationStack {
            ScrollViewReader { proxy in
                List {
                    // 隐藏的顶部锚点视图,不占用可视空间
                    Color.clear
                        .frame(height: 0)
                        .id(topAnchorID)
                    
                    Section {
                        ForEach(items) { item in
                            Text(item.title)
                                .id(item.id)
                        }
                    } header: {
                        Text("Header")
                    }
                }
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button("Top") {
                            withAnimation {
                                proxy.scrollTo(topAnchorID, anchor: .top)
                            }
                        }
                    }
                }
            }
        }
    }
}

说明

两种方案都能让List滚动到用户手指能触及的最顶端,完全贴合NavigationBar下方的位置,解决原代码仅滚动到第一个列表项顶部的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 19:24:50