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

SwiftUI如何显示无底部空行的List或Table?

SwiftUI List/Table 按固有尺寸显示(移除底部空白)

为啥默认List做不到?

SwiftUI的List本质是套了iOS的UITableView或macOS的NSTableView的壳,这些原生列表组件默认就会占满父容器的可用空间,根本不会自动收缩到刚好适配内容的高度。所以你加Spacer()或者fixedSize()都没用——原生组件的布局规则优先级比SwiftUI的固有尺寸逻辑高。

解决办法

办法1:用LazyVStack替代List(最简单)

如果不需要List的滑动删除、选中这些交互功能,直接用LazyVStack模拟List的样子就行,它会自动跟着内容高度走:

struct ContentView: View {
    let names = ["Achmed", "Balthus", "Chaim"]
    var body: some View {
        VStack {
            Text("List of Names")
                .font(.largeTitle)
                .padding()
            // 用LazyVStack+分隔线模拟List外观
            LazyVStack(spacing: 0) {
                ForEach(names, id: \.self) { name in
                    Text(name)
                        .padding(.vertical, 8)
                        .padding(.horizontal)
                    Divider() // 加分隔线还原List的分隔效果
                }
            }
            .border(.blue)
            .padding()
            Spacer()
        }
    }
}

办法2:手动设置List高度(保留原生交互)

要是必须用List的原生功能,那就自己算内容高度,给List设个固定frame:

struct ContentView: View {
    let names = ["Achmed", "Balthus", "Chaim"]
    // 单个cell的高度,根据你的字体/内容调整
    let cellHeight: CGFloat = 44
    
    var body: some View {
        VStack {
            Text("List of Names")
                .font(.largeTitle)
                .padding()
            List(names, id: \.self) { Text($0) }
                .listStyle(.plain) // 去掉默认的分组边距,更紧凑
                .frame(height: cellHeight * CGFloat(names.count))
                .border(.blue)
                .padding()
            Spacer()
        }
    }
}

要是cell内容高度不固定,得用GeometryReader或者动态计算文本高度的方法来获取准确的cell高度。

办法3:改原生列表的默认行为(iOS专属)

在iOS上,可以全局修改UITableView的设置,让它自动收缩:

// 放在App的初始化代码里,比如App.swift的init方法中
UITableView.appearance().tableFooterView = UIView()
// 如果不需要选中功能可以加下面这句,按需调整
// UITableView.appearance().allowsSelection = false

struct ContentView: View {
    let names = ["Achmed", "Balthus", "Chaim"]
    var body: some View {
        VStack {
            Text("List of Names")
                .font(.largeTitle)
                .padding()
            List(names, id: \.self) { Text($0) }
                .listStyle(.plain)
                .border(.blue)
                .padding()
            Spacer()
        }
    }
}

这个方法会全局改所有UITableView的行为,要是只想让单个List生效,就得用UIViewRepresentable封装自定义的UITableView。

补充:为啥fixedSize()没用?

fixedSize()是让视图用自己的固有尺寸,但List的固有尺寸被原生组件强制改成了父容器的高度,根本不是内容的高度。原生组件的布局逻辑优先级更高,所以fixedSize()起不了作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:33:16