SwiftUI изменить фильтр и обновить вид - PullRequest
0 голосов
/ 25 января 2020

Проблема в следующем, у меня есть массив продуктов , продукты имеют поле с именем productCategory , мне нужно обновить представление на основе примененного фильтра. Хорошее: хорошая часть в том, что я могу изменить фильтр, используя привязку, и когда это происходит, продукты исчезают. Проблема: я не знаю, как вызвать продукты, которые будут отображаться снова.

Где товары добавлены для просмотра:

struct ProductsList: View {
    var products = productsData
    var categories = categoryData
    @State var selectedCategory : String = ""
    var body: some View {

        VStack {
            HStack {
                ForEach(categories){ item in
                    //create the filter buttons
                    CategoryView(name : item.name, selectedCategory: self.$selectedCategory)
                }
            }
            ScrollView(.horizontal, showsIndicators: false) {
                    HStack{ // add the products to the view
                             if self.selectedCategory == item.productCategory {
                                ProductView(image: item.image, title: item.title, 
                                restaurant: item.restaurant, expensive: item.expensive,
                                productCategory: item.productCategory, restaurantCategory:
                                item.restaurantCategory, price: item.price,
                                weight: item.weight)
                        }

Где обновляется фильтр:

struct CategoryView: View {
    var name = ""
    @Binding var selectedCategory : String //filter that is binded to the view
    var body: some View {
        VStack {
            Button(action: {
                print("Button pressed")
                print(self.name)
                if self.selectedCategory != self.name { //change filter based on the button pressed
                    self.selectedCategory = ""
                    self.selectedCategory = self.name

                }
            }) {
                Text(name)
                    .font(.custom("Inter-Medium", size: 16))
                    .foregroundColor(Color("ProductSubtitle"))
            }
        }
    }
}

Есть идеи, как вспомнить ForEach для показа новых продуктов? На изображении прикреплены кнопки фильтра и категория товара. Пожалуйста, я застрял ...

enter image description here

Полный код ниже:


struct ProductsList: View {
   var products = productsData
   var categories = categoryData
   @State var selectedCategory : String = ""
   var body: some View {

       VStack {
           HStack {
               ForEach(categories){ item in
                   //create the filter buttons
                   CategoryView(name : item.name, selectedCategory: self.$selectedCategory)
               }
           }
           ScrollView(.horizontal, showsIndicators: false) {


               HStack{
                   //add products to the view
                   ForEach(products) { item in
                       if self.selectedCategory == "" {
                           ProductView(image: item.image, title: item.title, restaurant: item.restaurant, expensive: item.expensive, productCategory: item.productCategory, restaurantCategory: item.restaurantCategory, price: item.price,
                                       weight: item.weight)
                       }
                       else
                           if self.selectedCategory == item.productCategory {
                               ProductView(image: item.image, title: item.title, restaurant: item.restaurant, expensive: item.expensive, productCategory: item.productCategory, restaurantCategory: item.restaurantCategory, price: item.price,
                                           weight: item.weight)
                       }

                   }
                       //                    .frame(width: 210, height: 317)
                       .padding(.horizontal, 25)
               }



           }

       }
   }
}

struct ProductsList_Previews: PreviewProvider {
   static var previews: some View {
       ProductsList()
   }
}


struct products: Identifiable {
   var id = UUID()
   var image: String
   var title: String
   var restaurant: String
   var expensive: String
   var productCategory: String
   var restaurantCategory: String
   var price : String
   var weight : String
}


struct category: Identifiable {
   var id = UUID()
   var name: String
}



let categoryData = [
   category(name : "Burgers"),
   category(name : "Vegan"),
   category(name : "European"),
   category(name : "Pizza")
]


let productsData = [
   products(image: "Product1", title: "Spicy Chicken Burger", restaurant: "Lombardo's Bistro", expensive: "$$", productCategory: "Burger", restaurantCategory: "Fast Food", price: "8.99", weight: "415"),
   products(image: "Product2", title: "Big Tasty", restaurant: "Mc Donald's", expensive: "$$", productCategory: "Burger", restaurantCategory: "Fast Food", price: "11.99", weight: "355"),
   products(image: "Product1", title: "Pizza Diavola", restaurant: "Pizza Giovana", expensive: "$$", productCategory: "Pizza", restaurantCategory: "Italian", price: "13.99", weight: "515"),
   products(image: "Product2", title: "Crispy Strips", restaurant: "KFC", expensive: "$", productCategory: "Chicken", restaurantCategory: "Fast Food", price: "8.99", weight: "415")
]


struct ProductView: View {
   var image = "Image"
   var title = "Big Mc"
   var restaurant = "Mc Donald's"
   var expensive = "$"
   var productCategory = "Burger"
   var restaurantCategory = "Fast Food"
   var price = "8.99"
   var weight = "410"
   var body: some View {
       VStack(alignment: .leading){
           Image(image)
               .renderingMode(.original)
               .resizable()
               .aspectRatio(contentMode: .fit)
               .frame(width: 175, height: 160)
               .padding(.bottom, 8)
               .padding(.top, 10)

           Text(title)
               .font(.custom("Inter-SemiBold", size: 16))
               .foregroundColor(Color("ProductTitle"))
               .multilineTextAlignment(.center)

           Text(restaurant)
               .font(.custom("Inter-Regular", size: 12))
               .foregroundColor(Color("ProductSubtitle"))
               .padding(.bottom, 10)

           HStack {
               Text(expensive)

               Text("•" + productCategory)

               Text("•" + restaurantCategory)
           }
           .font(.custom("Inter-Regular", size: 8))
           .foregroundColor(Color("ProductSubtitle"))

           HStack(spacing: 2) {
               Text(price)
                   .font(.custom("Inter-SemiBold", size: 16))
                   .foregroundColor(Color("ProductTitle"))
               Text("/")
                   .font(.body)
                   .foregroundColor(.gray)
               Text(weight)
                   .font(.custom("Inter-Regular", size: 12))
                   .foregroundColor(Color("ProductSubtitle"))

               Spacer()

               Button(action: {}) {
                   Image(systemName: "plus")
                       .foregroundColor(Color(.white))

               }
               .padding(.horizontal, 12)
               .padding(.vertical, 12)
               .frame(width: 30, height: 30, alignment: .center)
               .background(Color(red: 0.843, green: 0.1, blue: 0.124))
               .clipShape(RoundedRectangle(cornerRadius: 15, style: .continuous))

           }
           .padding(.trailing , 15)
       }
       .background(Color(hue: 1.0, saturation: 0.0, brightness: 1.0))
   }
}


struct CategoryView: View {
   var name = ""
   @Binding var selectedCategory : String //filter that is binded to the view
   var body: some View {
       VStack {
           Button(action: {
               print("Button pressed")
               print(self.name)
               if self.selectedCategory != self.name {
                   self.selectedCategory = ""
                   self.selectedCategory = self.name

               }
           }) {
               Text(name)
                   .font(.custom("Inter-Medium", size: 16))
                   .foregroundColor(Color("ProductSubtitle"))
           }
       }
   }
}


Ссылка на GitHub: https://github.com/Bogdan-Blaj/FilterButtons

1 Ответ

1 голос
/ 25 января 2020

Проблема заключалась в том, что имя вашего фильтра не совпадало с вашим именем категории.

Если вы замените свой код на мой код, вы можете нажать «все», чтобы увидеть все, и «Бургеры», чтобы увидеть Бургеры.

другая проблема заключалась в том, что у вас не было кнопки / категории для «сброса» вашей категории, поэтому я добавил «все» для этого.

struct CategoryView: View {
    var name = ""
    @Binding var selectedCategory : String //filter that is binded to the view
    var body: some View {
        VStack {
            Button(action: {
                print("Button pressed")
                print(self.name)

                if self.selectedCategory != self.name {
                    self.selectedCategory = self.name

                }
                if self.selectedCategory == "Burgers" {
                    self.selectedCategory = "Burger"
                }

                if self.selectedCategory == "All" {
                    self.selectedCategory = ""
                }
            }) {
                Text(name)
                    .font(.custom("Inter-Medium", size: 16))
                    .foregroundColor(Color("ProductSubtitle"))
            }
        }
    }
}

let categoryData = [
    category(name : "All"),
    category(name : "Burgers"),
    category(name : "Vegan"),
    category(name : "European"),
    category(name : "Pizza")
]

и заменил это (я знаю, что это выглядит нелепо, но в противном случае, если вы нажмете Vegan (который будет пустой список, а затем нажмите все снова, ничего не происходит)

HStack{
                    //add products to the view
                    ForEach(products) { item in
                        if self.selectedCategory == "" {
                            ProductView(image: item.image, title: item.title, restaurant: item.restaurant, expensive: item.expensive, productCategory: item.productCategory, restaurantCategory: item.restaurantCategory, price: item.price,
                                        weight: item.weight)
                        }
                        else
                            if self.selectedCategory == item.productCategory {
                                ProductView(image: item.image, title: item.title, restaurant: item.restaurant, expensive: item.expensive, productCategory: item.productCategory, restaurantCategory: item.restaurantCategory, price: item.price,
                                            weight: item.weight)
                            } else {
                                Text("")
                            }

                        }
                        //                    .frame(width: 210, height: 317)
                        .padding(.horizontal, 25)
...