Created
November 8, 2019 18:22
-
-
Save NeoTeo/bc077d1072d780c32b42d51c4b6c2dca to your computer and use it in GitHub Desktop.
Investigation into ObservableObject
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
import SwiftUI | |
public class MyClass { | |
public var label: String = "init class" | |
func update(newLabel: String) { | |
label = newLabel | |
} | |
} | |
public struct MyStruct { | |
public var label: String = "init struct" | |
mutating func update(newLabel: String) { | |
label = newLabel | |
} | |
} | |
struct ContentView: View { | |
class MyObservableClass : ObservableObject { | |
@Published var myClass: MyClass! | |
@Published var myStruct: MyStruct! | |
} | |
@ObservedObject var myObservableObject = MyObservableClass() | |
init() { | |
self.myObservableObject.myClass = MyClass() | |
self.myObservableObject.myStruct = MyStruct() | |
} | |
var body: some View { | |
Form { | |
Section { | |
Text("Hello, World! \(myObservableObject.myClass.label)") | |
.onTapGesture { | |
// A @Published property of an ObservableObject emits before the property changes. | |
// In the case of myObservableObject if we make a change to the myStruct property things work as expected (the view body is refreshed) | |
// because myStruct is an instance of a struct. However, if we change the property of myClass then myObservableObject won't emit because | |
// myClass is a class instance which means that even if its properties change the instance itself does not. | |
self.myObservableObject.myClass.update(newLabel: "hej") | |
// We can force the update by calling objectWillChange.send() ... | |
// self.myObservableObject.objectWillChange.send() | |
// Or by creating a @Binding and accessing the wrapped value directly (not 100% on this one) | |
// self.$myObservableObject.myClass.label.wrappedValue = "woot" | |
} | |
Text("Hej, Verden! \(myObservableObject.myStruct.label)") | |
.onTapGesture { | |
self.myObservableObject.myStruct.update(newLabel: "hello") | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why would you use a class instead of a struct?
If you want to use Core Data managed objects in your views you have no choice.
Why wrap it in another ObservableObject class?
If you want to create a temporary instance of a Core Data managed object and can't use optionals.
Why shouldn't you be able to use optionals?
Because if you want to pass some of your model's properties to a TextField it won't accept bindings to optionals.