@Published property wrapper not working on subclass of ObservableObject
Finally figured out a solution/workaround to this issue. If you remove the property wrapper from the subclass, and call the baseclass objectWillChange.send() on the variable the state is updated properly.
NOTE: Do not redeclare let objectWillChange = PassthroughSubject<Void, Never>()
on the subclass as that will again cause the state not to update properly.
I hope this is something that will be fixed in future releases as the objectWillChange.send()
is a lot of boilerplate to maintain.
Here is a fully working example:
import SwiftUI
class MyTestObject: ObservableObject {
@Published var aString: String = ""
}
class MyInheritedObject: MyTestObject {
// Using @Published doesn't work on a subclass
// @Published var anotherString: String = ""
// If you add the following to the subclass updating the state also doesn't work properly
// let objectWillChange = PassthroughSubject<Void, Never>()
// But if you update the value you want to maintain state
// of using the objectWillChange.send() method provided by the
// baseclass the state gets updated properly... Jaayy!
var anotherString: String = "" {
willSet { self.objectWillChange.send() }
}
}
struct MyTestView: View {
@ObservedObject var myTestObject = MyTestObject()
@ObservedObject var myInheritedObject = MyInheritedObject()
var body: some View {
NavigationView {
VStack(alignment: .leading) {
TextField("Update aString", text: self.$myTestObject.aString)
Text("Value of aString is: \(self.myTestObject.aString)")
TextField("Update anotherString", text: self.$myInheritedObject.anotherString)
Text("Value of anotherString is: \(self.myInheritedObject.anotherString)")
}
}
}
}
SwiftUI - ObservableObject that inherits from NSObject does not update in iOS 13
It appears to be on iOS 13, if you subclass an object and do not conform to ObservableObject
directly (as in class SearchBarTester: ObservableObject
), you'll need to add this boilerplate code:
@Published var searchText: String = "" {
willSet {
objectWillChange.send()
}
}
However, calling the default objectWillChange
will still not work, hence you'll need to define it yourself again:
let objectWillChange = PassthroughSubject<Void, Never>()
swift ui handle property changed in observableObject
So I found the solution I wanted - the binding from model -> textfield was always working, but the value from textfield -> model I couldn't get working. The magic seems to be this keyword "willSet"
@Published var value : Double? = nil {
willSet( new_value ) {
print("going to save asynchronously now")
}}
works magically.
How to read property from a struct when being in @ObservableObject
ViewModel
class getJoke: ObservableObject {
@Published var currentDate = Date()
}
View that can change passing data
struct CustomDatePicker: View {
@Binding var currentDate: Date
var body: some View{
VStack {
DatePicker(selection: $currentDate, displayedComponents: .date){
Text("Select your date")
}
.datePickerStyle(.compact)
}
}
}
And put everything together
struct ContentView: View {
@StateObject var vm = getJoke()
var body: some View {
VStack(spacing: 40) {
CustomDatePicker(currentDate: $vm.currentDate)
Button {
print(vm.currentDate)
} label: {
Text("Show selected date")
}
}
}
}
Related Topics
Get the Frame of Uibarbuttonitem in Swift
Disable Bounce Effect in Uipageviewcontroller
Xcode 4.2: How to Import .H File from Subproject
Swiftui: Deleting Last Row in Foreach
How to Observe Changes in Userdefaults
How to Convert Date Like \/Date(1440156888750-0700)\/ to Something That Swift Can Handle
Xcode 8.1 Push Notifications in Swift 2.3 with Firebase Integration Not Getting
iOS 8 Uiactivityviewcontroller and Uialertcontroller Button Text Color Uses Window's Tintcolor
Hardware-Dependent Nsdateformatter Datefromstring: Bug (Returns Nil)
Swift - Error 'Expected ',' Separator' and 'Expected Expression in List of Expressions'
How to Convert Bytes to a Float Value in Swift
My Swift 4 Uiscrollview with Autolayout Constraints Is Not Scrolling
Split View Controller Must Be Root View Controller