TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

How can I prevent/debug updates of subviews not being affected by a @Published vars of a @StateObject (ObservableObject)

Forums > SwiftUI

When using a @StateObjects in my root view (ContentView) with multiple @Published vars I wanted to understand how the redrawing of views can be limited to the absolute minimum. Sometimes views are redrawn (due to a "@self changed" signal - see below) which should no need to be redrawn...

So here's a simple class with two properties

class UserProgress: ObservableObject {
    @Published var score : Int = 0 
    @Published var anotherScore : Int = 0
}

Each one should be rendered/used in separate Views

struct VarScoreView: View {
    var score: Int
    var body: some View {
        Self._printChanges()
        return VStack {
            Text("score (Var): \(self.score)")
        }
    }
}

struct VarAnotherScoreView: View {
    var anotherScore: Int
    var body: some View {
        Self._printChanges()
        return VStack {
            Text("an. score (Var): \(self.anotherScore)")
        }
    }
}

Additionally I have a button View which helps me to update the Observable Object:

struct ButtonView: View {
    @ObservedObject var progress: UserProgress

    var body: some View {
            VStack {
            Button("Increase Score") {
                progress.score += 1
            }
            Button("Increase another Score") {
                progress.anotherScore += 1
            }
        }
    }
}

Putting it all together

struct ContentView: View {

    @StateObject var up = UserProgress()

    var body: some View {
        print("------ changes detected in view -----")
        Self._printChanges()
        return VStack {
            ButtonView(progress: up)
            Spacer()
            VarScoreView(score: up.score)
            VarAnotherScoreView(anotherScore: up.anotherScore)
        }
    }
}

This produces the expected results visually and in the console 1) When clicking on the "Increas Score" Button:

------ changes detected in view -----
ContentView: _up changed.
VarScoreView: @self changed.

2) When clicking on the "Increase another Score" Buttong:

------ changes detected in view -----
ContentView: _up changed.
VarAnotherScoreView: @self changed.

But when I delete the Spacer() the VarScoreView also gets triggered for button "Increase another Score":

------ changes detected in view -----
ContentView: _up changed.
VarScoreView: @self changed.
VarAnotherScoreView: @self changed.

So the update of the VarScoreView seems to be triggered even though "up.score" is not updated just because of a layout issue?

How can I get deeper Insights into the inner Workings of "ContentView" to undersand the difference between the ContentView with and without the Spacer() (or other additional views)?

2      

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.