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
相关产品推荐
相关产品推荐

