Created
July 3, 2020 13:50
-
-
Save mjm/018c3458c84a3306f952ddc49c9e672e to your computer and use it in GitHub Desktop.
StateObject vs. ObservableObject
This file contains 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
// If you run this in a playground in Xcode 12, you can see the difference in behavior in the live view. | |
import SwiftUI | |
import PlaygroundSupport | |
class Counter: ObservableObject { | |
@Published var count: Int | |
init(_ initialCount: Int) { | |
self.count = initialCount | |
} | |
func increment() { | |
count += 1 | |
} | |
func decrement() { | |
count -= 1 | |
} | |
} | |
struct Counters: View { | |
@State var useFirstCounter = true | |
@StateObject var counter1 = Counter(0) | |
@StateObject var counter2 = Counter(0) | |
var body: some View { | |
VStack { | |
Counter1(counter: useFirstCounter ? counter1 : counter2) | |
Counter2(counter: useFirstCounter ? counter1 : counter2) | |
Button("Switch Counter") { | |
useFirstCounter.toggle() | |
} | |
} | |
} | |
} | |
// The Counter in this view will always be the one passed in from the parent view. | |
struct Counter1: View { | |
@ObservedObject var counter: Counter | |
init(counter: Counter) { | |
self.counter = counter | |
} | |
var body: some View { | |
HStack { | |
Button { counter.decrement() } label: { Image(systemName: "minus.circle") } | |
Text("\(counter.count)") | |
Button { counter.increment() } label: { Image(systemName: "plus.circle") } | |
} | |
} | |
} | |
// The Counter in this view will initially be set to the one passed in from the parent, | |
// but in later view updates, this will keep using that same instance every time, even | |
// if the parent later passes in a different Counter. | |
struct Counter2: View { | |
@StateObject var counter: Counter | |
init(counter: Counter) { | |
self._counter = StateObject(wrappedValue: counter) | |
} | |
var body: some View { | |
HStack { | |
Button { counter.decrement() } label: { Image(systemName: "minus.circle") } | |
Text("\(counter.count)") | |
Button { counter.increment() } label: { Image(systemName: "plus.circle") } | |
} | |
} | |
} | |
PlaygroundPage.current.setLiveView(Counters()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment