如何在SwiftUI中将两列按30%/70%的宽度比例拆分?
实现30%/70%宽度布局的最佳方式
要实现这个布局,核心是通过GeometryReader获取当前可用的屏幕宽度,然后分别为两个VStack设置对应比例的宽度。直接替换原代码中两个VStack的.frame修饰符即可,具体修改如下:
修改后的完整代码
GeometryReader { geo in HStack(alignment: .top, spacing: 3) { // 第一个VStack:占屏幕宽度30% VStack(alignment: .leading) { Text("Location") .font(.callout.weight(.semibold)) .lineLimit(1) if item.address != "" { Group { Text(item.address) Text(item.city + ", " + item.state) } .font(.footnote) .foregroundColor(.secondary) } else { Text("N/A") } } .frame(width: geo.size.width * 0.3, alignment: .leading) // 第二个VStack:占屏幕宽度70% VStack { HStack(alignment: .top, spacing: 3) { VStack(alignment: .leading) { Text("Weather") .font(.subheadline.weight(.semibold)) .lineLimit(1) HStack(spacing: 3) { Image(systemName: "waveform") .imageScale(.small) .foregroundColor(.secondary) Text("79%") .font(.caption.weight(.regular)) .foregroundColor(.secondary) } } .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) VStack(alignment: .leading) { Text("Reviews") .font(.subheadline.weight(.semibold)) .lineLimit(1) HStack(spacing: 3) { Image(systemName: "star") .imageScale(.small) .foregroundColor(.secondary) Text("4.7 (1212)") .font(.caption.weight(.regular)) .foregroundColor(.secondary) } } .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) } } .frame(width: geo.size.width * 0.7, alignment: .leading) .border(.red) } }
关键修改点说明
- 包裹GeometryReader:用GeometryReader整个包裹外层HStack,这样能拿到当前屏幕的实际宽度(
geo.size.width)。 - 替换第一个VStack的frame:把原来的
.frame(minWidth: 0, maxWidth: .infinity)改成.frame(width: geo.size.width * 0.3),直接固定为屏幕宽度的30%。 - 替换第二个VStack的frame:同理,改成
.frame(width: geo.size.width * 0.7),固定为屏幕宽度的70%。
额外说明
如果需要让HStack的spacing不占用比例分配的宽度(比如希望两个VStack的总宽度加上spacing等于屏幕宽度),可以调整计算方式:
// 计算可用宽度(减去spacing) let availableWidth = geo.size.width - 3 // 第一个VStack宽度 .frame(width: availableWidth * 0.3) // 第二个VStack宽度 .frame(width: availableWidth * 0.7)
内容的提问来源于stack exchange,提问作者SLE
相关产品推荐
相关产品推荐

