Это мое первое приложение SwiftUI. Я провел много поисков и не смог найти решение.
Я хочу отображать продукты из разных категорий. Для этого у меня есть меню с горизонтальной прокруткой на верхней панели. При выборе любой категории я хочу отображать продукты каждой категории. Когда при загрузке продукты первой категории отображаются правильно, но при выборе любой другой категории продукты не обновляются соответствующим образом. Однако, когда я перехожу к любому другому представлению и возвращаюсь к нему, продукты отображаются правильно.
Что я пробовал
Я пробовал разные представления для отображения продуктов, например Список / ScrollView. Не повезло.
Вот полный код моего View
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
}
}
Я был бы очень благодарен, если вы мне поможете разобраться в этом вопросе. С уважением