When browsing the product list, we need to search for the products we need. We can also build a collection shelf to save the products we need. We need to add stars to the products we like on the Row.

We need to add a field in Commodity to determine whether to collect the Commodity

Var isFavorite: BoolCopy the code

We need to add a control to the CommodityRow class to distinguish bookmarks

Image(commodity.isFavorite ? "shoucang1":"shoucang")
     .padding(.trailing)
Copy the code

Filter list View You can customize the list view to display all landmarks or only the user’s favorites. To do this, you need to add some status to the CommodityView type. A state is a value or set of values that can change over time and affect the behavior, content, or layout of a view. You can add State to the view using the property with the @state property.

struct CommodityView:View { @State private var showFavoritesOnly = true var filteredCommity:[Commodity] { Commoditys.filter { commodity in (! showFavoritesOnly || commodity.isFavorite) } } var body: some View { NavigationView { List(filteredCommity, id: \.id) { commodity in NavigationLink(destination: CommodityViewDetail(commodity: commodity)){ CommodityRow(commodity: NavigationTitle (" commodity ")}}.navigationTitle(" commodity ")}}Copy the code

We can add a button to switch the state on the interface, we can switch the state to view favorites function

struct CommodityView:View { @State private var showFavoritesOnly = true var filteredCommity:[Commodity] { Commoditys.filter { commodity in (! showFavoritesOnly || commodity.isFavorite) } } var body: some View { NavigationView { List { Toggle(isOn: $showFavoritesOnly) {Text(filteredCommity, id: \.id) {commodity in NavigationLink(destination: destination) NavigationTitle (CommodityViewDetail(commodity: commodity)){CommodityRow(commodity: commodity)}}. NavigationTitle (" commodity list ")}}}Copy the code

To prepare the user to control which particular landmarks are preferred, you first store the landmark data in an Observable. Observables are custom objects of data that can be bound to views stored in the SwiftUI environment. SwiftUI monitors any changes to the observables that may affect the view and displays the correct version of the view after the changes.

The observable needs to publish any changes to its data so that its subscribers can get the changes. With @ Published

@publish var Commoditys:[Commoditys] = load(" commoditys.json ")} final Class ModelData: ObservableObject {@publish var Commoditys:[Commodity] = load(" commoditys.json ")}Copy the code

In CommodityView.swift, add the @environmentobject property declaration to the view, HStack { Text(landmark.name) .font(.title) .foregroundColor(.primary) FavoriteButton(isSet: $modeldata.landmarks [landmarkIndex].isfavorite)} add the environmentObject(_:) modifier to the preview. As long as the environmentObject(_:) modifier has been applied to the parent, the modelData attribute automatically gets its value.

struct CommodityView:View { @State private var showFavoritesOnly = false @EnvironmentObject var modelData: ModelData var filteredCommity:[Commodity] { modelData.Commoditys.filter { commodity in (! showFavoritesOnly || commodity.isFavorite) } } var body: some View { NavigationView { List { Toggle(isOn: $showFavoritesOnly) {Text(filteredCommity, id: \.id) {commodity in NavigationLink(destination: destination) CommodityViewDetail(commodity: commodity)){ CommodityRow(commodity: Struct CommodityView_Previews: PreviewProvider {static var previews: some View { ForEach(["iPhone SE (2nd generation)", "iPhone XS Max"], id: \.self) { deviceName in CommodityView() .previewDevice(PreviewDevice(rawValue: deviceName)) .previewDisplayName(deviceName) .environmentObject(ModelData()) } } }Copy the code

Update SwiftUIDemoApp to create an instance of the model and serve it to the ContentView using the environmentObject(_:) modifier. The @StateObject property is used to initialize the model object for a given property only once during the life of the application. This is true both when you use this property in an application instance (as shown here) and when you use it in a view.

struct SwiftUIDemoApp: App {
    @StateObject private var modelData = ModelData()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(modelData)
        }
    }
}
Copy the code