视图未在“类别”菜单项选择SwiftUI

时间:2020-05-04 20:03:05

标签: swift swiftui scrollview

enter image description here这是我的第一个SwiftUI应用。我进行了很多搜索,但找不到解决方案。

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

我尝试过的事情

我尝试了不同的视图来显示诸如List / ScrollView之类的产品。没有运气。

这是我的视图的完整代码

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
    }
}

如果您能帮助我解决此问题,我将非常感谢。 最好的问候

1 个答案:

答案 0 :(得分:0)

原因是使用静态范围的ForEach构造函数,该构造函数在设计上不会发生任何更改,因此不会进行更新。

所以不要使用like

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()进行容器化,例如:in this post

相关问题