代码之家  ›  专栏  ›  技术社区  ›  Moses Harding

在SwiftUI的ForEach中以绑定和非绑定方式使用数组的单个成员,而不使用索引

  •  1
  • Moses Harding  · 技术社区  · 5 月前

    很抱歉,因为我是SwiftUI的新手-

    我有一个类(Meal),它包含另一个类的对象数组(Food)。我在这里试图实现的是能够添加食物并在列表中更新,然后能够通过点击来编辑单个食物。

    我正在迭代食物列表,并使用每种食物来(1)创建一个导航链接,(2)简单地在列表中列出食物的名称。问题是我得到了错误 Initializer 'init(_:)' requires that 'Binding<String>' conform to 'StringProtocol' 当我试图以一种“无约束”的方式引用食物时。具体来说,在下面的代码中,它位于行 Text(food.name) .

                ForEach($meal.foods) { food in
                    NavigationLink(destination: FoodView(food: food)) {
                        Text(food.name)
                    }
                }
    

    我知道我可以迭代索引列表( 我想 )但我认为这可能是不好的做法。我正在尝试找出在这种情况下的最佳实践是什么。提前感谢!

    完整代码如下:

    // MARK: Views
    struct ContentView: View {
        @State private var day = Day()
        
        var body: some View {
            MealView(meal: $day.meals.first!)
        }
    }
    
    struct MealView: View {
        @Binding var meal: Meal
        
        var body: some View {
            NavigationStack {
                List {
                    ForEach($meal.foods) { food in
                        NavigationLink(destination: FoodView(food: food)) {
                            Text(food.name)
                        }
                    }
                }
            }
     
        }
    }
    
    struct FoodView: View {
        @Binding var food: Food
        
        var body: some View {
            VStack {
                TextField("Food", text: $food.name)
            }
        }
    }
    
    // MARK: Data
    class Day {
        var meals: [Meal] = [Meal()]
    }
    
    @Observable
    class Meal: Identifiable {
        var id: UUID = UUID()
        var foods: [Food] = [Food(name: "Pizza"), Food(name: "Pasta"), Food(name: "Steak")]
    }
    
    @Observable
    class Food: Identifiable {
        var id: UUID = UUID()
        var name: String
        
        init(name: String) {
            self.name = name
        }
    }
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   Paulw11    5 月前

    错误显示

    Initializer 'init(_:)' requires that 'Binding<String>' conform to 'StringProtocol'

    这意味着 Text 初始化器想要符合以下条件的东西 StringProtocol Binding<String> 不; food 是a 装订<字符串> 。您需要访问绑定的字符串,可以使用绑定的 wrappedValue 财产-

    ForEach($meal.foods) { food in
        NavigationLink(destination: FoodView(food: food)) {
            Text(food.name.wrappedValue)
        }
    }