简体   繁体   中英

observableObject is not updating the view

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM