SwiftUI:如何同时实现Form Section行分隔与LazyVGrid列对齐?
实现Form中列对齐+行分隔的两种方案
针对你的需求,这里有两种实用的解决方案,既能保留列对齐效果,又能获得Form Section的行分隔符:
方案一:在LazyVGrid中手动添加跨列分隔符
直接在LazyVGrid的每行末尾添加Divider,并通过gridCellColumns让分隔符横跨所有列,模拟Form的行分隔效果:
let data = [("aaa","bbb","ccc"),("aaaaaaa","bb","ccccc"),("a","bbbbbb","cc"),("aaaa","bbbbbb","c")] Form { Section { LazyVGrid(columns: [ GridItem(.flexible(), alignment: .leading), GridItem(.flexible(), alignment: .leading), GridItem(.flexible(), alignment: .leading) ]) { ForEach(0..<data.count, id: \.self) { i in let datum = data[i] Text(datum.0) Text(datum.1) Text(datum.2) // 最后一行不加分隔符 if i != data.count - 1 { Divider() .gridCellColumns(3) // 让分隔符占满整行宽度 .padding(.horizontal) // 匹配Form分隔符的边距 } } } } }
优点:实现简单,复用原有的LazyVGrid布局逻辑;
注意:可根据需要调整Divider的padding或颜色,让它更贴近Form原生分隔符样式。
方案二:用HStack+动态列宽实现原生行分隔
通过计算每列文本的最大宽度,给HStack中的每个Text设置固定宽度,既保证列对齐,又保留Form自动生成的行分隔符:
// 定义PreferenceKey用于收集列宽度信息 struct ColumnWidthPreferenceKey: PreferenceKey { static var defaultValue: [CGFloat] = [0, 0, 0] static func reduce(value: inout [CGFloat], nextValue: () -> [CGFloat]) { let next = nextValue() value[0] = max(value[0], next[0]) value[1] = max(value[1], next[1]) value[2] = max(value[2], next[2]) } } struct ContentView: View { let data = [("aaa","bbb","ccc"),("aaaaaaa","bb","ccccc"),("a","bbbbbb","cc"),("aaaa","bbbbbb","c")] @State private var columnWidths: [CGFloat] = [0, 0, 0] var body: some View { Form { Section { ForEach(data, id: \.self) { datum in HStack { Text(datum.0) .background( GeometryReader { geo in Color.clear .preference(key: ColumnWidthPreferenceKey.self, value: [geo.size.width, 0, 0]) } ) .frame(width: columnWidths[0], alignment: .leading) Text(datum.1) .background( GeometryReader { geo in Color.clear .preference(key: ColumnWidthPreferenceKey.self, value: [0, geo.size.width, 0]) } ) .frame(width: columnWidths[1], alignment: .leading) Text(datum.2) .background( GeometryReader { geo in Color.clear .preference(key: ColumnWidthPreferenceKey.self, value: [0, 0, geo.size.width]) } ) .frame(width: columnWidths[2], alignment: .leading) } } } .onPreferenceChange(ColumnWidthPreferenceKey.self) { newWidths in columnWidths = newWidths } } } }
优点:完全复用Form原生的行分隔样式,布局逻辑更贴合SwiftUI的Form设计;
原理:通过GeometryReader获取每个文本的宽度,利用PreferenceKey收集并计算每列的最大宽度,最后给每个Text设置固定宽度实现对齐。
内容的提问来源于stack exchange,提问作者Ricky Mo
相关产品推荐
相关产品推荐

