我想显示一份用餐类别列表(例如:意大利美食,中国美食等)及其各自的用餐子列表(例如:比萨->意大利美食列表的一部分,面条->中国美食列表的一部分) 。
我正在使用元组,但是在执行上述操作时遇到了麻烦。先感谢您。
这是我的模拟数据
// MOCK DATA FOR NOW!!
class FoodListViewModel {
var meals: [Meal] = []
var mealCategories = [(String, Meal)]()
init() {
// Initiate the model (Meal) in here
fetchFood()
}
func fetchFood() {
let meal1 = Meal(id: 1, name: "Fettucine", imageName: "linguine", rating: 4, description: "Delicious Fettucine Linguine with a side of basil", price: 20.10, category: "italian")
let meal2 = Meal(id: 2, name: "Linguine", imageName: "linguine", rating: 4, description: "Delicious Fettucine Linguine with a side of basil", price: 20.10, category: "italian")
let meal3 = Meal(id: 3, name: "Spaghetti", imageName: "linguine", rating: 4, description: "Delicious Fettucine Linguine with a side of basil", price: 20.10, category: "italian")
let meal4 = Meal(id: 4, name: "Pesto", imageName: "linguine", rating: 4, description: "Delicious Fettucine Linguine with a side of basil", price: 20.10, category: "italian")
let meal5 = Meal(id: 5, name: "Noodles", imageName: "linguine", rating: 4, description: "Delicious Chao Ming with a side of basil", price: 20.10, category: "chinese")
let meal6 = Meal(id: 6, name: "Spicy Noodles", imageName: "linguine", rating: 4, description: "Delicious Chao Ming with a side of basil", price: 20.10, category: "chinese")
let meal7 = Meal(id: 7, name: "Tacos", imageName: "linguine", rating: 4, description: "Delicious Chao Ming with a side of basil", price: 20.10, category: "mexican")
meals.append(meal1)
meals.append(meal2)
meals.append(meal3)
meals.append(meal4)
meals.append(meal5)
meals.append(meal6)
meals.append(meal7)
mealCategories.append(("italian", meal1))
mealCategories.append(("italian", meal2))
mealCategories.append(("italian", meal3))
mealCategories.append(("italian", meal4))
mealCategories.append(("chinese", meal5))
mealCategories.append(("mexican", meal6))
}
}
进餐班struct Meal: Identifiable {
var id: Int
var name: String
var imageName: String
var rating: Int
var description: String
var price: Double
var category: String
init(id: Int, name: String, imageName: String, rating: Int, description: String, price: Double, category: String) {
self.id = id
self.name = name
self.imageName = imageName
self.rating = rating
self.description = description
self.price = price
self.category = category
}
}
这是我想如何显示它的粗略概念struct FoodListView: View {
var viewModel: FoodListViewModel
var body: some View {
NavigationView {
VStack {
ForEach(viewModel.mealCategories.key) { category in
Text("\(category)")
// Display list of meals (values) associated with this category (key) here
meals //
}
}
}
}
}
extension FoodListView {
var meals: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(viewModel.mealCategories.value) { meal in
NavigationLink(destination: FoodDetailView(viewModel: FoodDetailViewModel(meal: meal))) {
FoodListRowView(viewModel: FoodListRowViewModel(meal: meal))
}.buttonStyle(PlainButtonStyle())
}
}
}
}
}
这是FoodListRowView的代码struct FoodListRowView: View {
@ObservedObject var viewModel: FoodListRowViewModel
var body: some View {
ZStack {
Rectangle()
.fill(Color(red: 237/255, green: 239/255, blue: 241/255))
.frame(width: 250, height: 320, alignment: .center)
.cornerRadius(8)
.shadow(color: .gray, radius: 5, x: 0, y: -0.01)
VStack() {
Image("\(self.viewModel.meal.imageName)")
.resizable()
.frame(width: 250, height: 220, alignment: .top)
RatingView(rating: .constant(4))
Text("\(self.viewModel.meal.name)")
.bold()
.font(.largeTitle)
Text("\(self.viewModel.meal.price)$")
}.frame(width: 250, height: 320, alignment: .top)
}
}
}
这是FoodListRowViewModel的代码class FoodListRowViewModel: ObservableObject {
var meal: Meal
init(meal: Meal) {
self.meal = meal
}
}
最佳答案
首先,您可以将模型从元组更改为字典。这样,您的饭菜就可以轻松地按类别分组。
var mealCategories = [String: [Meal]]()
另外,由于您的Meal
结构已经具有category
字段,因此您可以循环填充mealCategories
:meals.forEach { meal in
mealCategories[meal.category, default: []].append(meal)
}
请注意,由于Swift中的字典是无序的,因此您可能需要对其进行排序。struct FoodListView: View {
...
var body: some View {
let categories = Array(viewModel.mealCategories.keys).sorted() // sorted list of categories
return NavigationView {
ScrollView(.vertical) {
ForEach(categories, id: \.self) { category in
VStack {
Text("\(category)")
self.categoryView(meals: self.viewModel.mealCategories[category, default: []])
}
}
}
}
}
}
和category
视图:extension FoodListView {
func categoryView(meals: [Meal]) -> some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(meals, id: \.id) { meal in
NavigationLink(destination: Text("meal")) {
FoodListRowView(viewModel: FoodListRowViewModel(meal: meal))
.padding()
}
.buttonStyle(PlainButtonStyle())
}
}
}
}
}