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

如何让SwiftUI分段Picker的宽度适配自身内容而非最宽分段?

SwiftUI分段Picker如何让各分段宽度适配自身内容?

默认使用.segmented样式的Picker会让所有分段统一适配最长选项的宽度,导致短内容的分段被不必要地拉长。比如以下代码:

func segments() -> [String] {
    var toReturn = Calendar.current.veryShortWeekdaySymbols
    toReturn.append("T")
    return toReturn
}

Picker("Day of week?", selection: $selectedDay) {
    ForEach(segments(), id: \.self) {
        Text($0)
            .scaledToFit()
    }
}
.pickerStyle(.segmented)
.fixedSize()

此时显示效果正常,各分段宽度适配自身内容:
显示效果1:短字符串分段正常显示

但如果将toReturn.append("T")改为添加更长的字符串toReturn.append("Tasks"),所有分段都会被拉宽以适配最长的"Tasks"选项:
显示效果2:长字符串导致所有分段被拉宽

解决方案:自定义分段选择器

原生.segmented样式不支持分段独立适配内容宽度,我们可以用HStack+Button模拟分段选择器,让每个分段根据自身内容调整宽度,同时实现选中状态的样式。

基础实现代码

@State private var selectedDay: String = ""

func segments() -> [String] {
    var toReturn = Calendar.current.veryShortWeekdaySymbols
    toReturn.append("Tasks")
    return toReturn
}

var body: some View {
    HStack(spacing: 0) {
        ForEach(segments(), id: \.self) { item in
            Button(action: {
                selectedDay = item
            }) {
                Text(item)
                    .padding(.horizontal, 12)
                    .padding(.vertical, 8)
                    .background(selectedDay == item ? Color.blue : Color.gray.opacity(0.2))
                    .foregroundColor(selectedDay == item ? .white : .primary)
                    .cornerRadius(6)
            }
            .buttonStyle(.plain)
        }
    }
    .fixedSize()
}

贴近原生样式的优化版

如果需要和原生分段Picker一样的两端圆角、中间无圆角效果,可以通过蒙版调整圆角:

HStack(spacing: 0) {
    ForEach(Array(segments().enumerated()), id: \.element) { index, item in
        Button(action: {
            selectedDay = item
        }) {
            Text(item)
                .padding(.horizontal, 12)
                .padding(.vertical, 8)
                .background(
                    RoundedRectangle(cornerRadius: 6)
                        .fill(selectedDay == item ? Color.blue : Color.gray.opacity(0.2))
                        .mask({
                            HStack {
                                if index == 0 {
                                    Rectangle()
                                        .cornerRadius(6, corners: [.topLeft, .bottomLeft])
                                } else if index == segments().count - 1 {
                                    Rectangle()
                                        .cornerRadius(6, corners: [.topRight, .bottomRight])
                                } else {
                                    Rectangle()
                                }
                            }
                        })
                )
                .foregroundColor(selectedDay == item ? .white : .primary)
        }
        .buttonStyle(.plain)
    }
}
.fixedSize()

这种自定义方案不仅能让每个分段宽度适配自身内容,还能自由调整选中/未选中的样式、内边距等,比原生Picker更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:36:02