Created
December 5, 2025 07:51
-
-
Save LidorFadida/8ff251820638c9edd57a1df11e21a5eb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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