You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)
    }
}

关键修改点说明

  1. 包裹GeometryReader:用GeometryReader整个包裹外层HStack,这样能拿到当前屏幕的实际宽度(geo.size.width)。
  2. 替换第一个VStack的frame:把原来的.frame(minWidth: 0, maxWidth: .infinity)改成.frame(width: geo.size.width * 0.3),直接固定为屏幕宽度的30%。
  3. 替换第二个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:50:37