I have two Views (main and filter). For my filter view, there are Pickers that the user can choose from that will filter data that is hardcoded inside an array. In the main view, the array is being called within a for each loop that will display the data on a LazyVGrid view. However, for some reason, the view is not updating when I filter the data.
The Filter view
import SwiftUI
struct Filter: View {
@Binding var sortIndex: Int
@ObservedObject var model: MarketDataViewModel
var sort = ["Best Match", "Newest", "Lowest to Highest", "Highest to Lowest"]
var body: some View {
Form {
Section(header: Text("General Settings")){
Picker(selection: $sortIndex, label: Text("Sort by")) {
ForEach(0..<sort.count) {
Text(self.sort[$0])
}
}.onChange(of: sortIndex, perform: { value in
model.data.sort(by: {$0.price < $1.price})
print(model.data)
print("__________________________________")
})
} .navigationBarTitle("Filters")
}
}
The Main view
import SwiftUI
struct MarketPlace: View {
@State var text = ""
@State var sortIndex = 0
@State private var isEditing = false
@StateObject var item = MarketDataViewModel()
var body: some View {
NavigationView {
VStack {
HStack{
SearchBar(text: $text)
NavigationLink(destination: Filter(sortIndex: $sortIndex, model: MarketDataViewModel())) {
Image("Filter")
.resizable()
.frame(width: 33, height: 33, alignment: .trailing)
}
Spacer()
.frame(width: 15)
}
ScrollView {
LazyVGrid(columns: [.init(), .init()]) {
ForEach(item.data.filter({"\($0.itemName)".contains(text) || text.isEmpty})) { item in
NavigationLink(destination: DescriptionView(item: item), label: {
GroupBox(
label: Image(item.image)
.resizable()
.scaledToFit()
.frame(width: 100,height: 100)
.cornerRadius(4)
.padding(.vertical, 10)
.padding(.horizontal, 20)
) {
VStack(alignment: .center, spacing: 5) {
Text(item.itemName)
.fontWeight(.semibold)
.foregroundColor(Color.black)
.lineLimit(2)
.minimumScaleFactor(0.5)
Text("$\(item.price, specifier: "%.2f")")
.font(.subheadline)
.foregroundColor(.secondary)
}
}
})
}
}
.padding()
}
}
.navigationBarHidden(true)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
Data
struct MarketData : Identifiable {
var id = UUID()
var itemName = String()
var image = String()
var description = String()
var price = Double()
var pfp = String()
}
class MarketDataViewModel: ObservableObject {
@Published var data: [MarketData] = [MarketData(id: UUID(), itemName: "Boots", image: "Boots", description: "Just a pair of boots", price: 30.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Santa", image: "Santa", description: "Ho Ho Ho. I am santa", price: 100.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Snowflake", image: "Snowflake", description: "Snow", price: 0, pfp: "Profile"), MarketData(id: UUID(), itemName: "Car", image: "Car", description: "The most expensive thing on this entire database right now.", price: 100000000, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Robo Boots", image: "Robot Boots", description: "Bootleg IronMan", price: 3440.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Boots SM", image: "Boots", description: "Just a pair of boots", price: 310.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Boots M", image: "Boots", description: "Just a pair of boots", price: 500.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Boots XXL", image: "Boots", description: "Just a pair of boots", price: 30.40, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Boots For Sale", image: "Boots", description: "Just a pair of boots", price: 31.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Boots Not For Sale", image: "Boots", description: "Just a pair of boots", price: 60.00, pfp: "Profile"),
MarketData(id: UUID(), itemName: "Fake Boots", image: "Boots", description: "Just a pair of boots", price: 10.00, pfp: "Profile")]
}
here, NavigationLink(destination: Filter(sortIndex: $sortIndex, model: MarketDataViewModel()))
you create a new MarketDataViewModel
every time you click on it. You should have: NavigationLink(destination: Filter(sortIndex: $sortIndex, model: item))
. That way you use the single source of truth, your @StateObject var item = MarketDataViewModel()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.