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

如何在SwiftUI中用Switch Case实现带跳转动作的按钮列表

SwiftUI实现带不同跳转目标的按钮列表(Switch Case方式)

核心方案

原代码通过两个分离数组管理按钮文本和图标,且所有按钮跳转至同一页面。我们可以通过Switch Case匹配按钮索引(或封装的类型)来返回不同目标视图,同时推荐用结构体统一管理菜单数据,提升代码可维护性。

方案一:封装数据+枚举匹配(推荐)

先封装菜单数据,再用枚举标记跳转类型,通过Switch Case匹配对应视图:

struct Dashboard: View { // 修正Swift命名规范:结构体首字母大写
    // 定义跳转类型枚举
    enum MenuDestination {
        case myOrders, payments, settings, password
    }
    
    // 封装单个菜单的所有信息
    struct MenuItem {
        let text: String
        let imageName: String
        let destination: MenuDestination
    }
    
    // 初始化菜单数据
    private let menuItems: [MenuItem] = [
        MenuItem(text: "My Orders", imageName: "wallet.pass", destination: .myOrders),
        MenuItem(text: "Payments", imageName: "trophy", destination: .payments),
        MenuItem(text: "Settings", imageName: "gearshape", destination: .settings),
        MenuItem(text: "Password", imageName: "lock.circle", destination: .password)
    ]
    
    var body: some View {
        VStack {
            ForEach(menuItems.indices, id: \.self) { index in
                let item = menuItems[index]
                NavigationLink {
                    // Switch Case匹配跳转目标
                    switch item.destination {
                    case .myOrders:
                        MyOrdersView()
                            .navigationBarHidden(true)
                    case .payments:
                        PaymentsView()
                            .navigationBarHidden(true)
                    case .settings:
                        SettingsView()
                            .navigationBarHidden(true)
                    case .password:
                        PasswordView()
                            .navigationBarHidden(true)
                    }
                } label: {
                    // 原按钮UI结构,替换为封装的数据
                    HStack {
                        HStack {
                            Image(systemName: item.imageName)
                                .resizable()
                                .frame(minWidth: 30, maxWidth: 30, minHeight: 30, maxHeight: 35)
                                .padding(15)
                                .foregroundColor(.white)
                                .background {
                                    Rectangle()
                                        .foregroundColor(.orange)
                                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                                        .cornerRadius(50)
                                }
                                .padding(.horizontal, 10)
                            
                            Text(item.text)
                                .font(.system(size: 20))
                                .bold()
                                .foregroundColor(.black)
                                .frame(maxWidth: .infinity, maxHeight: 40, alignment: .leading)
                            
                            Image(systemName: "chevron.right")
                                .resizable()
                                .frame(maxWidth: 15, maxHeight: 20)
                                .bold()
                                .foregroundColor(.gray)
                        }
                        .padding(.horizontal, 30)
                        .padding(.vertical, 10)
                    }
                }
            }
        }
    }
}

// 替换为你的实际目标视图
struct MyOrdersView: View {
    var body: some View { Text("我的订单页面") }
}
struct PaymentsView: View {
    var body: some View { Text("支付页面") }
}
struct SettingsView: View {
    var body: some View { Text("设置页面") }
}
struct PasswordView: View {
    var body: some View { Text("密码设置页面") }
}

方案二:直接通过索引匹配(轻量场景)

如果不想封装数据,也可以直接遍历索引,用Switch Case判断跳转目标:

struct Dashboard: View {
    var categoriesText = ["My Orders", "Payments", "Settings", "Password"]
    var categoriesImage = ["wallet.pass", "trophy", "gearshape", "lock.circle"]
    
    var body: some View {
        VStack{
            ForEach(0..<categoriesImage.count) { i in
                NavigationLink {
                    // 根据索引匹配跳转视图
                    switch i {
                    case 0:
                        MyOrdersView()
                            .navigationBarHidden(true)
                    case 1:
                        PaymentsView()
                            .navigationBarHidden(true)
                    case 2:
                        SettingsView()
                            .navigationBarHidden(true)
                    case 3:
                        PasswordView()
                            .navigationBarHidden(true)
                    default:
                        EmptyView() // 处理超出索引的异常情况
                    }
                } label: {
                    // 原按钮UI代码不变
                    HStack{
                        HStack{
                            Image(systemName: categoriesImage[i])
                                .resizable()
                                .frame(minWidth: 30 ,maxWidth: 30, minHeight: 30, maxHeight: 35)
                                .padding(15)
                                .foregroundColor(.white)
                                .background(){
                                    Rectangle()
                                        .foregroundColor(.orange)
                                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                                        .cornerRadius(50)
                                }
                                .padding(.horizontal,10)
                        
                            Text(categoriesText[i])
                                .font(.system(size: 20))
                                .bold()
                                .foregroundColor(.black)
                                .frame(maxWidth: .infinity, maxHeight: 40, alignment: .leading)
                        
                            Image(systemName: "chevron.right")
                                .resizable()
                                .frame(maxWidth: 15, maxHeight: 20)
                                .bold()
                                .foregroundColor(.gray)
                        }
                        .padding(.horizontal, 30)
                        .padding(.vertical, 10)
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:45:32