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

SwiftUI中如何让HStack内两按钮取较宽按钮的宽度一致

问题描述

我正尝试创建一个包含两个按钮的HStack,代码如下:

struct SwiftUIView: View {
    var body: some View {
        HStack {
            Button("Short") { }
            Button("Rather long") { }
        }
        .buttonStyle(.bordered)
    }
}

想要实现的效果是让两个按钮宽度相同,且都等于其中较宽按钮的宽度。

已尝试以下无法达到预期效果的方案:

  • fixedSize(horizontal: true, vertical: false)修饰符——仅在VStack中生效
  • frame(maxWidth: .infinity)修饰符——虽有效果但会让按钮填满屏幕宽度,不符合设计需求
  • frame(width: 80.0)——虽有效果但在标签文字变长或字号增大时失效

请问还有其他解决方案吗?

解决方案

方案一:自定义PreferenceKey获取最大宽度(兼容iOS 13+)

通过自定义PreferenceKey捕获两个按钮的宽度,取最大值后统一设置给两个按钮,代码实现如下:

// 定义用于传递宽度的PreferenceKey
struct WidthPreferenceKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = max(value, nextValue())
    }
}

struct SwiftUIView: View {
    @State private var maxButtonWidth: CGFloat = 0
    
    var body: some View {
        HStack(spacing: 16) { // 可自定义按钮间距
            Button("Short") { }
                .background(
                    GeometryReader { geo in
                        Color.clear
                            .preference(key: WidthPreferenceKey.self, value: geo.size.width)
                    }
                )
                .frame(width: maxButtonWidth)
            
            Button("Rather long") { }
                .background(
                    GeometryReader { geo in
                        Color.clear
                            .preference(key: WidthPreferenceKey.self, value: geo.size.width)
                    }
                )
                .frame(width: maxButtonWidth)
        }
        .buttonStyle(.bordered)
        .onPreferenceChange(WidthPreferenceKey.self) { newValue in
            maxButtonWidth = newValue
        }
    }
}

方案二:使用Grid布局(iOS 16+)

iOS 16及以上提供的Grid布局默认会让同一行的元素宽度对齐,直接就能实现需求,代码更简洁:

struct SwiftUIView: View {
    var body: some View {
        Grid(horizontalSpacing: 16) { // 自定义按钮间距
            GridRow {
                Button("Short") { }
                Button("Rather long") { }
            }
        }
        .buttonStyle(.bordered)
    }
}

两种方案的特点:

  • 方案一兼容性强,适配更早的iOS版本;
  • 方案二代码简洁,适合已升级到iOS 16+的项目。

内容的提问来源于stack exchange,提问作者Malburrito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:07:14