PAYATHON 2026

SwiftUI 如何在 Button 中直接使用 Picker 的选中项执行函数?

数据小许

在 Button 的操作闭包中直接对 selectedFunction 使用 switch。Picker 已通过 $selectedFunction 更新状态,点击按钮时读取当前值即可,无需增加 SelectMyFuncString。

修改后的代码

删除 SelectMyFuncString 和负责给它赋值的整段 switch selectedFunction 视图代码,然后把按钮中的判断改为:

import SwiftUI

struct ContentView: View {
    enum myFuncPicker: String, CaseIterable, Identifiable {
        case myfunc1
        case myfunc2
        case myfunc3

        var id: Self { self }
    }

    @State private var selectedFunction: myFuncPicker = .myfunc1

    var body: some View {
        VStack {
            Picker(selection: $selectedFunction, label: Text("select Function")) {
                Text("myfunc1").tag(myFuncPicker.myfunc1)
                Text("myfunc2").tag(myFuncPicker.myfunc2)
                Text("myfunc3").tag(myFuncPicker.myfunc3)
            }

            Button("Button") {
                switch selectedFunction {
                case .myfunc1:
                    print("func1")
                case .myfunc2:
                    print("func2")
                case .myfunc3:
                    print("func3")
                }
            }
            .padding()
        }
    }
}

代码保留了原来的 print,用来展示各个分支。实际使用时,将它们替换为对应的函数调用。

为什么可以直接读取选中项?

@State 保存当前选择,$selectedFunction 为 Picker 提供读写该状态的 Binding。用户选择选项后,Picker 会将对应 .tag(...) 的枚举值写入 selectedFunction。

Button 的操作闭包可以访问同一个状态,因此点击按钮时,直接判断 selectedFunction 就能决定执行哪个分支。无需在两个控件之间额外传递字符串,也无需添加 .onChange 来同步另一份状态。

使用时注意什么?

  • Picker 中每个 .tag(...) 的类型应与 selectedFunction 一致,这里都是 myFuncPicker。
  • selectedFunction 的初始值是 .myfunc1,因此用户未更改选择就点击按钮时,会执行第一个分支。
  • 当前枚举只有三个成员,switch 已覆盖全部情况,不需要 default。
  • .onAppear 是视图出现时执行的回调,不适合用来维护选中项与另一份状态的映射。删除重复状态后,也就无需处理二者的同步。

Picker 选项中的 Text 仍用于显示名称。仅为触发 .onAppear 赋值而添加的 Text 可以删除;如果还需要展示“已选择哪个函数”,可以保留提示文字,直接根据 selectedFunction 生成显示内容。

备注:内容仅供参考。