首页 > 解决方案 > Navigation Link - 通过 NavigationLink 和列表将特定的数组元素传递给新视图

问题描述

我有一个名为recipeArray的数组,它显示在列表中。单击列表项时,用户会被带到一个名为RecipeItemDetailView的新视图。该数组包含一些默认值作为占位符。

struct StoredRecipeModel: Identifiable {
var id = UUID()
var name: String
var recipeSteps: [String]

}

struct ContentView: View {

@State var recipeArray: [StoredRecipeModel] = [StoredRecipeModel(name: "one", recipeSteps: ["step1 here", "step1b", "Step1c"]), StoredRecipeModel(name: "two", recipeSteps: ["step2here"]), StoredRecipeModel(name: "three", recipeSteps: ["Step3here"])]

var body: some View {
    NavigationView {
            VStack {
                List(recipeArray, id: \.id) { index in NavigationLink(destination: RecipeItemDetailView(recipe: $recipeArray, listItem: ListIndex.init())) {
                        HStack {
                            Text(index.name)
                            
                        }
                    }
                }

RecipeItemDetailView(用户单击列表项时导航到的视图)中,我只想显示给定元素的数据。例如,如果用户单击列表中的第一项(标记为“One”),我只想显示该给定元素的recipeSteps - 在本例中为 ["step1 here", "step1b", "Step1c "]。

我当前的代码向前传递整个数组。有没有办法只传递与给定索引相关的元素 - 例如单击的索引?

编辑 - 添加额外的 RecipeItemDetailView 代码

导入 SwiftUI

结构RecipeItemDetailView:查看{

@Binding var recipe: [StoredRecipeModel]
@Environment(\.presentationMode) var presentationMode
//@ObservedObject var listItem: ListIndex
var recipeDataToReturn = 0


var body: some View {
    
    var stored = [recipe[recipeDataToReturn].recipeSteps]
    
    NavigationView {
        VStack {
            List(stored[0], id: \.self) { index in Text(index)}
   
            List {
                Section(header: Text("Section")) {
                    Button("print") {
                        print(stored)
                    }
                }
            }

        }
    }
}

}

标签: swiftxcodeswiftuistateswiftui-navigationlink

解决方案


如果你只需要配方而不需要绑定,这很容易——只需将你在List闭包中获得的变量传递给你的详细视图:

struct ContentView: View {
    
    @State var recipeArray: [StoredRecipeModel] = [StoredRecipeModel(name: "one", recipeSteps: ["step1 here", "step1b", "Step1c"]), StoredRecipeModel(name: "two", recipeSteps: ["step2here"]), StoredRecipeModel(name: "three", recipeSteps: ["Step3here"])]
    
    var body: some View {
        NavigationView {
            VStack {
                List(recipeArray, id: \.id) { recipe in
                    NavigationLink(destination: RecipeItemDetailView(recipe: recipe)) {
                        HStack {
                            Text(recipe.name)
                        }
                    }
                }
            }
        }
    }
}
struct RecipeItemDetailView : View {
    var recipe: StoredRecipeModel
    
    var body: some View {
        Text(recipe.name)
    }
}

如果你需要一个绑定,你可以通过索引获得它:


struct ContentView: View {
    
    @State var recipeArray: [StoredRecipeModel] = [StoredRecipeModel(name: "one", recipeSteps: ["step1 here", "step1b", "Step1c"]), StoredRecipeModel(name: "two", recipeSteps: ["step2here"]), StoredRecipeModel(name: "three", recipeSteps: ["Step3here"])]
    
    var body: some View {
        NavigationView {
            VStack {
                List(recipeArray.indices, id: \.self) { index in
                    NavigationLink(destination: RecipeItemDetailView(recipe: $recipeArray[index])) {
                        HStack {
                            Text(recipeArray[index].name)
                        }
                    }
                }
            }
        }
    }
}

struct RecipeItemDetailView : View {
    @Binding var recipe: StoredRecipeModel
    
    var body: some View {
        Text(recipe.name)
    }
}

或者,编写一个 Binding 将 id 绑定到元素:


struct ContentView: View {
    
    @State var recipeArray: [StoredRecipeModel] = [StoredRecipeModel(name: "one", recipeSteps: ["step1 here", "step1b", "Step1c"]), StoredRecipeModel(name: "two", recipeSteps: ["step2here"]), StoredRecipeModel(name: "three", recipeSteps: ["Step3here"])]
    
    func bindingForId(id: UUID) -> Binding<StoredRecipeModel> {
        .init {
            recipeArray.first(where: { $0.id == id}) ?? StoredRecipeModel(name: "", recipeSteps: [])
        } set: { newValue in
            recipeArray = recipeArray.map {
                return $0.id == id ? newValue : $0
            }
        }
    }
    
    var body: some View {
        NavigationView {
            VStack {
                List(recipeArray, id: \.id) { recipe in
                    NavigationLink(destination: RecipeItemDetailView(recipe: bindingForId(id: recipe.id))) {
                        HStack {
                            Text(recipe.name)
                        }
                    }
                }
            }
        }
    }
}

struct RecipeItemDetailView : View {
    @Binding var recipe: StoredRecipeModel
    
    var body: some View {
        Text(recipe.name)
    }
}

更新,基于评论:

struct RecipeItemDetailView : View {
    @Binding var recipe: StoredRecipeModel
    
    var body: some View {
        NavigationView {
            VStack {
                List(recipe.recipeSteps, id: \.self) { item in
                    Text(item)
                }
                
                List {
                    Section(header: Text("Section")) {
                        Button("print") {
                            print(recipe)
                        }
                    }
                }
            }
        }
    }
}


推荐阅读