Skip to content

Instantly share code, notes, and snippets.

@LidorFadida
Created December 5, 2025 07:51
Show Gist options
  • Select an option

  • Save LidorFadida/8ff251820638c9edd57a1df11e21a5eb to your computer and use it in GitHub Desktop.

Select an option

Save LidorFadida/8ff251820638c9edd57a1df11e21a5eb to your computer and use it in GitHub Desktop.
class ParentViewModel: ObservableObject {
@Published var counter1: Int = 0
@Published var counter2: Int = 0
}
/// When using an `ObservableObject`, the first mutation of any `@Published` property
/// triggers a full re-computation of the parent view and all of its child views.
/// This initial update causes both `CounterView` instances to lose their previous
/// identity and re-render. After this first invalidation pass, SwiftUI appears to
/// stabilize the view identities, and subsequent updates only re-render the
/// `CounterView` whose `Binding` actually changed.
struct ParentWithViewModel: View {
@StateObject var viewModel = ParentViewModel()
var body: some View {
VStack(spacing: 24.0) {
CounterView(name: "counter 1", count: $viewModel.counter1)
.border(Color.red)
CounterView(name: "counter 2", count: $viewModel.counter2)
.border(Color.blue)
}
}
}
/// The classic "demystifying" example without `ObservableObject` works as expected
/// only the relevant child view is re-rendered even in first mutations.
struct ParentWithState: View {
@State private var counter1: Int = 0
@State private var counter2: Int = 0
var body: some View {
VStack(spacing: 24.0) {
CounterView(name: "counter 1", count: $counter1)
.border(Color.red)
CounterView(name: "counter 2", count: $counter2)
.border(Color.blue)
}
}
}
struct CounterView: View {
let name: String
@Binding var count: Int
var body: some View {
if #available(iOS 15, *) {
let _ = print("🤖", #function, "name:", name, Self._printChanges())
}
VStack {
Text("name: \(name)")
Text("count: \(count)" )
HStack {
Button("Increase") {
print("🤖", #function, "counter: \(name) increasing")
count += 1
}
Button("Decrease") {
print("🤖", #function, "counter: \(name) decreasing")
count -= 1
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment