如何在iPhone上用SwiftUI实现对齐的表格数据展示?
解决方案
一、让SwiftUI Table在iPhone正常显示所有列
SwiftUI的Table组件在iPhone上默认会折叠成仅显示第一列的列表样式,只需设置特定的tableStyle就能让它展开显示完整表格:
struct Stats: Identifiable { let id = UUID() let name: String let totalMatches: Int let standingsPoints: Int } struct StandingsView: View { let statsList: [Stats] = [ Stats(name: "闪电队", totalMatches: 10, standingsPoints: 25), Stats(name: "飓风队", totalMatches: 10, standingsPoints: 22), Stats(name: "雄鹰队", totalMatches: 10, standingsPoints: 18) ] var body: some View { Table(statsList) { TableColumn("球队", value: \.name) { stats in Text(stats.name) .frame(maxWidth: .infinity, alignment: .leading) } TableColumn("已赛场次", value: \.totalMatches) { stats in Text("\(stats.totalMatches)") .frame(maxWidth: .infinity, alignment: .trailing) } TableColumn("积分", value: \.standingsPoints) { stats in Text("\(stats.standingsPoints)") .frame(maxWidth: .infinity, alignment: .trailing) } } .tableStyle(.inset) // 核心设置:让iPhone展示完整列 .navigationTitle("积分榜") } }
- 给每个
TableColumn内部的文本设置对齐方式,实现球队列左对齐、其余列右对齐的需求 .inset样式会让Table在iPhone上以多列形式展示,而非折叠列表
二、用HStack实现列对齐
如果坚持用HStack+List的方案,需要给每列设置统一的宽度,保证各行的对应列对齐:
方案1:固定宽度(适合需求明确的场景)
struct StandingsView: View { let statsList: [Stats] = [ Stats(name: "闪电队", totalMatches: 10, standingsPoints: 25), Stats(name: "飓风队", totalMatches: 10, standingsPoints: 22), Stats(name: "雄鹰队", totalMatches: 10, standingsPoints: 18) ] var body: some View { List { // 表头 HStack { Text("球队") .frame(width: 150, alignment: .leading) Spacer() Text("已赛场次") .frame(width: 80, alignment: .trailing) Text("积分") .frame(width: 60, alignment: .trailing) } .font(.headline) ForEach(statsList) { stats in HStack { Text(stats.name) .frame(width: 150, alignment: .leading) Spacer() Text("\(stats.totalMatches)") .frame(width: 80, alignment: .trailing) Text("\(stats.standingsPoints)") .frame(width: 60, alignment: .trailing) } } } .navigationTitle("积分榜") } }
方案2:动态适配宽度(适配不同屏幕尺寸)
用GeometryReader获取父视图宽度,按比例分配各列宽度:
struct StandingsView: View { let statsList: [Stats] = [ Stats(name: "闪电队", totalMatches: 10, standingsPoints: 25), Stats(name: "飓风队", totalMatches: 10, standingsPoints: 22), Stats(name: "雄鹰队", totalMatches: 10, standingsPoints: 18) ] var body: some View { List { GeometryReader { geo in VStack(spacing: 16) { // 表头 HStack { Text("球队") .frame(width: geo.size.width * 0.5, alignment: .leading) Text("已赛场次") .frame(width: geo.size.width * 0.25, alignment: .trailing) Text("积分") .frame(width: geo.size.width * 0.25, alignment: .trailing) } .font(.headline) ForEach(statsList) { stats in HStack { Text(stats.name) .frame(width: geo.size.width * 0.5, alignment: .leading) Text("\(stats.totalMatches)") .frame(width: geo.size.width * 0.25, alignment: .trailing) Text("\(stats.standingsPoints)") .frame(width: geo.size.width * 0.25, alignment: .trailing) } } } } .listRowInsets(EdgeInsets()) // 移除默认内边距,让列占满宽度 } .navigationTitle("积分榜") } }
内容的提问来源于stack exchange,提问作者Zonker.in.Geneva
相关产品推荐
相关产品推荐

