0

I have a list here of news articles

I am trying to give the user the opportunity to save or unsave a news article. The Save button saves it on the backend but the image does not update when the backend updates.

@State var industryInsights = [IndustryInsight]()

    List {
        ForEach(industryInsights, id: \.self) { insight in
            IndustryInsightRowView(insight: insight)
        }
    }

I am not sure the best way of doing this, but I would like the button image to update as the user presses the button. Any help would be appreciated.

InsightClass and properties

struct IndustryInsight: Codable, Hashable, Identifiable {
    let id: Int
    let industry, alert, date: String
    let url: String
    let status: String
}

Function when save button pressed.

func saverowButtonClicked(alert: IndustryInsight) {
    if alert.status == "Saved" {
        RestAPI.changeStatusIndustryAlerts(id: alert.id, status: "Unsave", completionHandler: { () in
        })
    } else {
        RestAPI.changeStatusIndustryAlerts(id: alert.id, status: "Save", completionHandler: { () in
        })
    }
}
  • In SwiftUI you can't really reload an individual row, just let the system handle it. In the `changeStatusIndustryAlerts` closure, modify your `industryInsights` array and the List will automatically update. – aheze Jul 06 '21 at 16:42
  • @aheze thank you, could you show me what you mean.. the industryInsights Array is in another class though – Luke Tomlinson Jul 06 '21 at 16:44
  • 1
    You'll need to update your `industryInsights` `@State` variable. – jnpdx Jul 06 '21 at 16:45
  • @LukeTomlinson what class is your `saverowButtonClicked` func in? It's got to be related to your ContentView somehow – aheze Jul 06 '21 at 16:46
  • @aheze I have a RowView() with all those functions in it when a button is pressed. Then In my contentView() I have a List of RowView() – Luke Tomlinson Jul 06 '21 at 16:49
  • Might want to consider using a `Binding` for `IndustryInsightRowView`'s `insight` property, so any changes there will be passed back up to `ContentView`. Note that you'll need to [loop over `industryInsights`'s indices](https://stackoverflow.com/a/57837054/14351818) instead, unless you're developing for iOS 15? – aheze Jul 06 '21 at 16:56
  • @aheze I did this, and I am still having the same problem. – Luke Tomlinson Jul 06 '21 at 17:56
  • @aheze I need the property of Status to be reloaded when changeStatus is called – Luke Tomlinson Jul 06 '21 at 17:56
  • How did you implement the Hashable protocol for IndustryInsight struct? If done in the right way it should fire the reload of a row when changed – DungeonDev Mar 12 '22 at 23:24

1 Answers1

1

I am trying to avoid using @State as much as possible and using @ObservableObject and @Published instead. Try converting your IndustryInsight struct to an ObservableObject class and let IndustryInsightRowView accept it as an @ObservedObject.

Guy Nir
  • 1,098
  • 9
  • 7