分类菜单项选择SwiftUI时,视图没有更新。

问题描述 投票:0回答:1

enter image description here这是我的第一个SwiftUI应用。我做了很多搜索,却找不到解决方法。

我想显示不同类别的产品。为此,我有一个顶栏水平滚动的菜单,当选择任何类别时,我想显示每个类别的产品。当选择任何类别时,我想显示每个类别的产品。当加载第一个类别时,产品显示正确,但选择任何其他类别时,产品没有相应的更新。然而,当我导航到任何其他视图并返回到这个视图时,产品显示正确。

我试过的方法

我尝试了不同的视图来显示产品,比如ListScrollView。但没有成功。

以下是我的视图的完整代码

struct ProductListView: View {

    @State var data:[Product]
    @State private var categoryItems:[Product] = []
    @State private var uniqueCategories:[Product] = []
    @State private var numberOfRows:Int  = 0
    @State private var selectedItem:Int  = 0
    @State private var image:UIImage?

    @EnvironmentObject var authState: AuthenticationState

    @ViewBuilder
    var body: some View {

        NavigationView{
            VStack{
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack {
                        ForEach(0..<self.data.removingDuplicates(byKey: { $0.category }).count) { i in
                            Text(self.data.removingDuplicates(byKey: { $0.category })[i].category)
                                .underline(self.selectedItem == i ? true:false, color: Color.orange)
                                .foregroundColor(self.selectedItem == i ? Color.red:Color.black)
                                //.border(Color.gray, width: 2.0)
                                .overlay(
                                    RoundedRectangle(cornerRadius: 0.0)
                                        .stroke(Color.init(red: 236.0/255.0, green: 240.0/255.0, blue: 241.0/255.0), lineWidth: 1).shadow(radius: 5.0)
                            ).padding(.horizontal)
                                //.shadow(radius: 5.0)

                                .onTapGesture {

                                    self.selectedItem = i
                                    _ = self.getSelectedCategoryProducts()
                                    print("Category Items New Count: \(self.categoryItems.count)")


                            }
                            Spacer()
                            Divider().background(Color.orange)
                        }
                    }
                }
                .frame(height: 20)

                Text("My Products").foregroundColor(Color.red).padding()

                Spacer()

                if(self.data.count == 0){
                    Text("You didn't add any product yet.")
                }

                if (self.categoryItems.count>0){

                    ScrollView(.vertical){

                        ForEach(0..<Int(ceil(Double(self.categoryItems.count)/2.0)), id: \.self){ itemIndex in
                            return HStack() {

                                NavigationLink(destination:ProductDetailView(index: self.computeIndexes(currentIndex: itemIndex,cellNo: 1), data: self.categoryItems, image: UIImage())){


                                    ProductTile(index: self.computeIndexes(currentIndex: itemIndex, cellNo: 1), data: self.categoryItems, image: UIImage())


                                }

                                NavigationLink(destination:ProductDetailView(index: self.computeIndexes(currentIndex: itemIndex,cellNo: 2), data: self.categoryItems, image: UIImage())){
                                    ProductTile(index: self.computeIndexes(currentIndex: itemIndex, cellNo: 2), data: self.categoryItems, image: UIImage())
                                }

                            }.padding(.horizontal)
                        }


                    }.overlay(
                        RoundedRectangle(cornerRadius: 10.0)
                            .stroke(Color.init(red: 236.0/255.0, green: 240.0/255.0, blue: 241.0/255.0), lineWidth: 1).shadow(radius: 5.0)
                    )
                }
            }

        }

        .onAppear(perform: {

            _ = self.getSelectedCategoryProducts()

            //print("Loading updated products....")
            if (self.authState.loggedInUser != nil){
                FireStoreManager().loadProducts(userId: self.authState.loggedInUser!.uid) { (isSuccess, data) in

                    self.data = data

                }
            }
        })

            .padding()


    }

    func populateUniqueCategories() -> [Product] {

        let uniqueRecords = self.data.reduce([], {
            $0.contains($1) ? $0 : $0 + [$1]
        })

        print("Unique Items: \(uniqueRecords)")

        return uniqueRecords
    }

    func getSelectedCategoryProducts() -> [Product] {

        var categoryProducts:[Product] = []

        self.data.forEach { (myProduct) in
            if(myProduct.category == self.populateUniqueCategories()[selectedItem].category){
                categoryProducts.append(myProduct)
            }
        }
        self.categoryItems.removeAll()
        self.categoryItems = categoryProducts
        return categoryProducts
    }
    func computeIndexes(currentIndex:Int, cellNo:Int) -> Int {
        var resultedIndex:Int = currentIndex

        if (cellNo == 1){
            resultedIndex = resultedIndex+currentIndex
            print("Cell 1 Index: \(resultedIndex)")
        }else{
            resultedIndex = resultedIndex + currentIndex + 1
            print("Cell 2 Index: \(resultedIndex)")
        }
        return resultedIndex
    }
}

这就是数组扩展

    extension Array {
    func removingDuplicates<T: Hashable>(byKey key: (Element) -> T)  -> [Element] {
        var result = [Element]()
        var seen = Set<T>()
        for value in self {
            if seen.insert(key(value)).inserted {
                result.append(value)
            }
        }

        return result
    }
}

如果你能帮我解决这个问题,我将会非常感激。

swift swiftui scrollview
1个回答
0
投票

原因是在使用静态范围ForEach构造函数,它不期望任何变化,通过设计,所以不更新。

因此,而不是使用像

ForEach(0..<self.data.removingDuplicates(byKey: { $0.category }).count) { i in
       ^^^^^^ range !!

ForEach(0..<Int(ceil(Double(self.categoryItems.count)/2.0)), id: \.self){
        ^^^^ range

它需要使用直接的数据容器,如

ForEach(self.data.removingDuplicates(byKey: { $0.category }), id: \.your_product_id) { product in
        ^^^^^^^^^  array

注意:如果你在迭代过程中需要索引,可以通过使用 .enumerated() 到容器,例如 在这个职位上

© www.soinside.com 2019 - 2024. All rights reserved.