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

在SwiftUI中实现从一个视图向另一个视图传递并展示数据

实现Recipe列表到详情页的跳转与数据传递

没问题,我帮你搞定这个需求,分几步来实现:

第一步:修改详情视图,让它能接收选中的Recipe数据

首先你的RecipeController目前是硬编码使用整个食谱列表,我们需要改成接收单个选中的RecipeListModel对象,这样才能展示对应的数据:

struct RecipeController: View {
    @State var recipeEdit = true
    // 新增:添加属性接收选中的食谱对象
    var selectedRecipe: RecipeListModel
    
    var body: some View {
        NavigationView{
            VStack{
                // 替换成展示选中食谱的名称
                Text(selectedRecipe.name)
                    .font(.title)
                // 如果RecipeEntryPicture需要展示对应食谱的图片,也要给它传参(示例见最后补充)
                RecipeEntryPicture(selectedRecipe: selectedRecipe)
                RecipeIngredients(isEditing: $recipeEdit)
                // 你还可以在这里添加更多展示选中食谱信息的控件,比如食材列表、烹饪步骤等
            }
            .toolbar{
                ToolbarItem(placement: .bottomBar){
                    Button(action: {
                        recipeEdit.toggle()
                    }){
                        HStack{
                            Image(systemName: "pencil.circle").foregroundColor(.black)
                            Text(recipeEdit ? "Edit" : "Complete")
                                .foregroundColor(.black)
                        }
                        .font(.title)
                    }
                    .edgesIgnoringSafeArea(.all)
                    .frame(maxWidth: .infinity)
                    .frame(height: 60)
                    .background(Color(recipeEdit ? "spaceGray" : "completeGreen"))
                }
            }
            // 设置导航栏标题为选中食谱的名称
            .navigationTitle(selectedRecipe.name)
        }
    }
}

第二步:在列表视图实现跳转逻辑

这里有两种常用的实现方式,你可以根据需求选择:

方式1:直接用NavigationLink包裹按钮(最简单)

这种方式适合不需要额外前置逻辑的场景,点击按钮直接跳转:

struct RecipeListView: View {
    var listofRecipes: [RecipeListModel] = RecipeList.recipes
    
    init(){
        UITableView.appearance().backgroundColor = .clear
    }
    
    var body: some View {
        NavigationView{
            VStack{
                Text("Recipes")
                    .padding(.top, 40)
                    .font(.title2)
                
                List(listofRecipes, id: \.id){ recipe in
                    HStack{
                        Image(recipe.image)
                            .resizable()
                            .frame (width: 70, height:70)
                            .cornerRadius(15)
                        
                        VStack{
                            Text(recipe.name)
                                .font(.title3)
                            
                            // 用NavigationLink包裹按钮,点击即跳转并传递当前recipe
                            NavigationLink(destination: RecipeController(selectedRecipe: recipe)) {
                                Text("View Recipe")
                                    .font(.body)
                                    .foregroundColor(.white)
                                    .frame(width:120, height:30)
                                    .background(Color("completeGreen"))
                            }
                        }
                        .padding(.leading, 40)
                    }
                }
            }
        }
    }
}

方式2:用状态变量控制跳转(适合需要前置逻辑的场景)

如果需要在跳转前做一些额外操作(比如打印日志、数据校验、网络请求),可以用状态变量结合隐藏的NavigationLink:

struct RecipeListView: View {
    var listofRecipes: [RecipeListModel] = RecipeList.recipes
    // 新增:存储选中的食谱,用来控制跳转状态
    @State private var selectedRecipe: RecipeListModel? = nil
    
    init(){
        UITableView.appearance().backgroundColor = .clear
    }
    
    var body: some View {
        NavigationView{
            VStack{
                Text("Recipes")
                    .padding(.top, 40)
                    .font(.title2)
                
                List(listofRecipes, id: \.id){ recipe in
                    HStack{
                        Image(recipe.image)
                            .resizable()
                            .frame (width: 70, height:70)
                            .cornerRadius(15)
                        
                        VStack{
                            Text(recipe.name)
                                .font(.title3)
                            
                            Button(action: {
                                // 这里可以添加跳转前的额外逻辑,比如:
                                print("即将跳转至食谱:\(recipe.name)")
                                // 标记选中的食谱,触发跳转
                                selectedRecipe = recipe
                            }){
                                Text("View Recipe")
                                    .font(.body)
                                    .foregroundColor(.white)
                                    .frame(width:120, height:30)
                                    .background(Color("completeGreen"))
                            }
                        }
                        .padding(.leading, 40)
                    }
                }
                // 隐藏的NavigationLink,当selectedRecipe不为空时自动跳转
                .background(
                    NavigationLink(
                        destination: RecipeController(selectedRecipe: selectedRecipe!),
                        isActive: Binding(
                            get: { selectedRecipe != nil },
                            set: { if !$0 { selectedRecipe = nil } }
                        )
                    ) {
                        EmptyView()
                    }
                )
            }
        }
    }
}

补充:给子视图传递选中的Recipe数据

如果你的RecipeEntryPicture需要展示对应食谱的图片,也要给它添加接收参数的属性:

struct RecipeEntryPicture: View {
    var selectedRecipe: RecipeListModel
    
    var body: some View {
        Image(selectedRecipe.image)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .cornerRadius(15)
            .padding()
    }
}

可选:iOS 16+推荐使用NavigationStack

如果你是针对iOS 16及以上版本开发,建议用NavigationStack替代NavigationView,用法基本一致,只需要把NavigationView换成NavigationStack即可,更适合复杂的导航场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:04:07