SwiftUI复杂对齐场景实现:无硬编码同时满足居中和leading对齐
实现方案
你可以通过两种方式实现需求,全程不需要硬编码任何尺寸参数:
方案1:iOS 16+ 推荐(Grid布局)
用SwiftUI原生Grid可以自动处理同列元素的宽度对齐,整个区块会自适应内容宽度后自动居中:
struct TestView: View { let values: [(String, String)] = [ ("03", "30.123"), ("02", "33.222"), ("01", "completed") ] var body: some View { Grid(horizontalSpacing: 24) { ForEach(values, id: \.1) { tuple in GridRow { Text(tuple.0) Text(tuple.1) } } } .frame(maxWidth: .infinity, alignment: .center) .frame(width: 350, height: 250) // 模拟外层容器尺寸 } }
- 特性:Grid会自动匹配同列的最大宽度,所有行的leading边缘天然对齐,就算后续内容变长,也只会扩展对应列的宽度,整个区块的居中位置不会偏移。
方案2:低版本兼容(PreferenceKey测量)
如果需要支持iOS 16以下的版本,可以通过PreferenceKey自动测量列宽实现对齐:
struct TestView: View { let values: [(String, String)] = [ ("03", "30.123"), ("02", "33.222"), ("01", "completed") ] @State private var firstColMaxWidth: CGFloat = 0 @State private var secondColMaxWidth: CGFloat = 0 var body: some View { LazyVStack(alignment: .leading, spacing: 8) { ForEach(values, id: \.1) { tuple in HStack(spacing: 24) { Text(tuple.0) .background( GeometryReader { geo in Color.clear.preference(key: FirstColWidthKey.self, value: geo.size.width) } ) .frame(width: firstColMaxWidth, alignment: .leading) Text(tuple.1) .background( GeometryReader { geo in Color.clear.preference(key: SecondColWidthKey.self, value: geo.size.width) } ) .frame(width: secondColMaxWidth, alignment: .leading) } } } .onPreferenceChange(FirstColWidthKey.self) { firstColMaxWidth = $0 } .onPreferenceChange(SecondColWidthKey.self) { secondColMaxWidth = $0 } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .frame(width: 350, height: 250) } } private struct FirstColWidthKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = max(value, nextValue()) } } private struct SecondColWidthKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = max(value, nextValue()) } }
- 逻辑:通过PreferenceKey自动计算两列的最大宽度,统一给所有行的对应列设置相同宽度,保证所有行对齐,整个列表块自动在外层容器中居中。
内容的提问来源于stack exchange,提问作者New Dev
相关产品推荐
相关产品推荐

