UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to update a view on property change?

Forums > SwiftUI

Hello dear swiftui learners;-)

I have been trying to create a simple workout application, hovever it seems I have skipped some basics and can't make my views update on property change

here is my code:

import SwiftUI

@main
struct TestAppApp: App {
@StateObject var manager = HealthKitManager()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(manager)
        }
    }
}

struct ContentView: View {
    @EnvironmentObject var manager: HealthKitManager

    var body: some View {
        ScrollView {
            ForEach(manager.activities.sorted(by: {$0.value.id < $1.value.id}), id: \.key) { item in
                ActivityCard(activity: item.value)
            }
        }
        .refreshable {
            manager.update()
        }
    }
}

struct Activity: Identifiable {
    var id: Int
    var title: String
    var amount: Int
}

struct ActivityCard: View {
    @State var activity: Activity
    var body: some View {
        VStack {
            Text(activity.title)
            Text("\(activity.amount)")
        }
    }
}

class HealthKitManager: ObservableObject {
    @Published var activities: [String : Activity] = [
        "steps": Activity(id: 1, title: "Steps", amount: 0),
        "calories": Activity(id: 2, title: "Calories", amount: 0)
    ]

    func update() {
        let activity = Activity(id: 3, title: "Distance", amount:  10)
        self.activities["distance"] = activity // this work
        self.activities["steps"]?.amount = 10 // this does not!
        print(self.activities) // but it's updated
    }
}

if I add new activity to activities it will work, but if i try to update property of existing activity it's no luck.

chatgpt suggested to change struct to class - not working

class Activity: Identifiable, ObservableObject {
    var id: Int
    var title: String
    @Published var amount: Int

    init(id: Int, title: String, amount: Int) {
        self.id = id
        self.title = title
        self.amount = amount
    }
}

another suggestion was objectWillChange.send() - not working

        objectWillChange.send()
        self.activities["steps"]?.amount = 10
        objectWillChange.send()

I have been trying everything, can somebody please help me?

thank you!

Peter

   

@Peter is stuck and offered this observation:

hovever it seems I have skipped some basics .....

Yes! Yes you have.

I wonder where you learned about @ObservableObject and @Published? Did you learn these techniques from the 100 Days of SwiftUI course that's available free on this terrific web site?

   

for these interested.. https://www.hackingwithswift.com/books/ios-swiftui/sharing-swiftui-state-with-observable answers my question if I understand it right

@Observable
class Activity: Identifiable {
    var id: Int
    var title: String
    var amount: Int

    init(id: Int, title: String, amount: Int) {
        self.id = id
        self.title = title
        self.amount = amount
    }
}
func update() {
      var activity = Activity(id: 3, title: "Distance", amount:  10)

      self.activities["distance"] = activity // this works
      self.activities["steps"]?.amount = 100 // this now works too!

      var act = Activity(id: 1, title: "Steps", amount:  20)
      self.activities["steps"]=act // not working

      self.activities.removeValue(forKey: "steps") // also not working
      // previous removeValue would work without next line = MAGIC! ;-)
      self.activities["steps"]=act

      print("\(self.activities["steps"]?.amount ?? 0)")
  }

can't help myself but I am finding swift and especially swiftUI too magic for my taste

can somebody please explain me what is going on?

   

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.