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

SwiftUI中如何在Menu内显示Segmented样式的Picker?

解决SwiftUI Menu中Segmented样式Picker无法显示的问题

问题原因

SwiftUI的Menu组件的内容容器是为列表型控件(如Button、MenuPicker等)设计的,.segmented样式的Picker需要特定的横向布局空间和渲染环境,Menu的内部上下文不支持直接渲染该样式的Picker,因此会出现无法显示的情况。

解决方案

方案一:自定义模拟Segmented选择器

在Menu内部用HStack+Button组合模拟Segmented的外观和交互:

struct MenuView: View {
    var pick = ["1", "2", "3", "4"]
    @State var selected = "1"
    
    var body: some View {
        Menu {
            Button{} label: {
                Text("Button1")
            }
            
            // 自定义Segmented风格选择器
            HStack(spacing: 0) {
                ForEach(pick, id: \.self) { option in
                    Button(action: {
                        selected = option
                        // 选择后关闭Menu
                        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                    }) {
                        Text(option)
                            .padding(.horizontal, 12)
                            .padding(.vertical, 6)
                            .background(selected == option ? Color.blue.opacity(0.2) : Color.clear)
                            .cornerRadius(4)
                    }
                }
            }
            .padding(.vertical, 4)
            
        } label: {
            Text("Menu (\(selected))")
        }
    }
}
  • 用背景色区分选中状态,点击选项后自动关闭Menu
  • 样式可根据需求自定义调整(比如圆角、颜色等)

方案二:通过Popover/Sheet展示原生Segmented Picker

将Segmented Picker放在Menu外部的弹窗中,通过Menu中的Button触发显示:

struct MenuView: View {
    var pick = ["1", "2", "3", "4"]
    @State var selected = "1"
    @State var showPickerPopover = false
    
    var body: some View {
        Menu {
            Button{} label: {
                Text("Button1")
            }
            
            Button(action: {
                showPickerPopover = true
            }) {
                Text("Select Option: \(selected)")
            }
            
        } label: {
            Text("Menu")
        }
        .popover(isPresented: $showPickerPopover) {
            Picker("select one", selection: $selected) {
                ForEach(pick, id: \.self){
                    Text($0)
                }
            }
            .pickerStyle(.segmented)
            .padding()
            .onChange(of: selected) { _ in
                showPickerPopover = false // 选择后自动关闭弹窗
            }
        }
    }
}
  • 保留原生Segmented Picker的交互体验
  • 弹窗会在选择选项后自动关闭,也可添加确认按钮手动关闭

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:50:51