【问题标题】:How to pass data from a view to another view in SwiftUI?如何在 SwiftUI 中将数据从视图传递到另一个视图?
【发布时间】:2021-12-13 10:09:48
【问题描述】:

我正在处理一个大问题,我尝试了很多方法来解决这个问题,但确实没有找到合适的答案。

基本上,我有一个食物菜单列表,当我点击它们时,我想显示它们的内容,如能量、蛋白质、脂肪、碳水化合物等,但显示的只是一些 ID。我的后端有一件棘手的事情。

我会把代码放在下面,我会逐步解释:

这里是食物菜单:Food menus photo

List {
            Section(header: Text(Texts.meniuriViewText1)) {
                    ForEach(syncViewModel.menu.filter({$0.type == 1359})) { men in
                    HStack {
                        NavigationLink(destination: ItemMenuView(meniu: men)) {
                       Image("healthyMeal")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 100, height: 100)
                            .padding()
                        VStack(alignment: .leading, spacing: 10) {
                            Text(men.name)
                                .font(.system(size: 16))
                                .foregroundColor(.black)
                                .fontWeight(.semibold)
                            HStack {
                                Text("\(men.price) lei")
                                    .fontWeight(.bold)
                                
                                Text("\(men.ingredients[0].grams, specifier: "%.0f")g")
                                    .font(.system(size: 16))
                                    .fontWeight(.medium)
                                    .foregroundColor(.gray)
                            }
                        }
                    }
                        Spacer()
                            Image(systemName: "plus")
                                .font(.title)
                                .foregroundColor(Color.onboardingColor)
                                .padding(20)
                                .onTapGesture {
                                    coreDataViewModel.addTask(name: men.name, grams: men.ingredients[0].grams, price: Int(men.price))
                                }
                        }
       
                }
                
            }
}
            

这是关于食物菜单的详细信息:Details photo

var meniu : Meniuri?

var body: some View {
  VStack {
                    HStack {
                        Text("Ingrediente")
                            .foregroundColor(.gray)
                            .padding(30)
                        Spacer()
                    }
                    ForEach(meniu!.ingredients) { men in
                        HStack(spacing: 15) {
                            
                            Image("aubergine")
                                .padding(.leading, 30)
                            
                            Text("\(men.ingredient)")
                                .foregroundColor(.colorGrayDark)
                            
                            Spacer()
                            Text("\(men.grams, specifier: "%.0f")g")
                                .foregroundColor(.colorGrayDark)
                                .padding(.trailing, 30)
                            
                        }
                    }
                        .padding(.bottom, 15)
}

这是我的菜单模型“Meniuri”:

struct Meniuri: Codable, Identifiable{

let id: Int
    let meta: ExtrasOptionMeta
    let name: String
    let ingredients: [Ingredients]
    let type, price: Int

}

struct Ingredients: Codable, Identifiable{
    var id: Int { ingredient }
    let ingredient: Int
    let grams: Double
}

现在解释一下,成分模型中的“成分”属性在我的后端与此成分模型“项目链接”,因此成分中的成分属性基本上是成分模型中的 id。如何在“食物菜单的详细信息”中访问成分模型中的成分?

struct Ingredient: Model, Identifiable {
    static var itemName: String = "ingredient"
    var id: Int
    var meta: Meta
    var name: String
    var energy: Double
    var protein, fats, carbohydrates, fiber: Double?
    var saturatedFats, sugar, monosaturatedFats, polysaturatedFats: Double?
    var cholesterol, calcium: Int?
    var iron, magnesium: Double?
    
}

这就是我从互联网上检索数据的方式:

 func fetchMenus() {
        _spaceOne.fetch(path: "/api/items", parameters: ["q" : "at'test' select item from 'menu'"]) { result in
            switch result {
        case .failed(let error):
            print(error)
            break
        case .success(_, let data, _):
            do{
                let meniu = try JSONDecoder().decode([Meniuri].self, from: data)
                    self.menu = meniu
            
            } catch {
                print(error)
            }
            break
        }
        }
    }


func fetchIngredients ()  {
        _spaceOne.fetch(Ingredient.self).all{ result in
            switch result {
        case .failed(let error):
            print(error)
            break
            case .success(let ingred):
                self._ingredient = ingred
            }
        }
        }

【问题讨论】:

  • 我认为所有 swiftui 代码都与问题无关,这是关于您的数据源以及如何构建模型数据的问题。我不明白您实际上是如何获取成分的,但一种解决方案可能是将所有成分加载到缓存(字典)中,并使用 id 属性作为键从那里检索它们。另一种选择是使用从后端获得的模型,而是将其映射到另一个模型中,在其中将 Ingredients 对象替换为 Ingredient 对象,并可能进行一些其他更改以使模型对你更有用。
  • 我在之前的评论中说过这都是关于模型层的,但您也可以考虑在模型和视图之间使用一些视图模型或控制器类,具体取决于您采用的路径。
  • 你好@JoakimDanielson。首先,感谢您的回答。像这篇文章中用于获取成分和菜单的所有网络功能都在视图模型中。第二:我如何映射到另一个模型来用成分替换成分?
  • 这对我来说很难回答,因为不清楚您是如何获取数据的
  • 请澄清您的具体问题或提供更多详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。

标签: swift list swiftui


【解决方案1】:

这是一个简单的例子:

struct ContentView: View {
  var body: some View {
      NavigationView {
          NavigationLink(destination: FeatureView1(title: "FeatureView1")) {
            Text("Go to FeatureView1")
          }
      }
  }
}

struct FeatureView1 : View {
  var title: String

  var body: some View {
     Text(title)
     NavigationLink(destination: FeatureView2(title: "FeatureView2")) {
        Text("Go to FeatureView2")
     }
  }
}

struct FeatureView2 : View {
  var title: String

  var body: some View {
     Text(title)
  }
}

根据你的用例,还有很多其他的方法可以在视图之间共享数据,我让你稍后看到@EnvironmentObject、@Binding 等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 2022-11-29
    • 2021-08-04
    • 2021-11-09
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    相关资源
    最近更新 更多