I am having a difficulty with a Binding property inside a view mannequin that is being created in one other view mannequin. Right here is simplified model of two views:
struct ContentView: View {
@StateObject var viewModel = ContentViewModel()
var physique: some View {
VStack {
// binding via `@Revealed var toggleViewModel`
ToggleWrapperView(viewModel: viewModel.toggleViewModel)
// binding via `var isOnBinding: Binding<Bool>`
ToggleWrapperView(viewModel: ToggleViewModel(isOn: viewModel.isOnBinding!, title: "Binding via isOnBinding"))
// binding via `@Revealed var isOn`
ToggleWrapperView(viewModel: ToggleViewModel(isOn: $viewModel.isOn, title: "Binding via view"))
}
.padding()
}
}
struct ToggleWrapperView: View {
var viewModel: ToggleViewModel
var physique: some View {
VStack {
Toggle(isOn: viewModel.$isOn, label: {
Textual content(viewModel.title + " (viewModel.isOn)")
})
}
}
}
And listed here are view fashions for the views:
class ContentViewModel: ObservableObject {
@ObservedObject var dataManager = DataManager()
@Revealed var toggleViewModel: ToggleViewModel!
@Revealed var isOn: Bool = false // Property for the binding within the ContentView
personal var privateIsOnForBinding: Bool = false
var isOnBinding: Binding<Bool>?
init() {
toggleViewModel = ToggleViewModel(isOn: $dataManager.isOn, title: "Binding from DataManager")
initBinding()
}
func initBinding() {
isOnBinding = Binding {
self.privateIsOnForBinding
} set: { updatedValue in
self.privateIsOnForBinding = updatedValue
print(self.isOnBinding!)
}
}
}
struct ToggleViewModel {
@Binding var isOn: Bool
let title: String
}
class DataManager: ObservableObject {
@Revealed var isOn: Bool = false {
didSet {
print("did set DataManager.isOn (isOn)")
}
}
}
From the ToggleWrapperView
examples above solely binding created with $viewModel.isOn
is working as anticipated on toggle motion.
Within the instance with toggleViewModel
I can see that the property in DataManager
is being up to date (print within the property observer), however the binding itself stays false
Binding<Bool>(transaction: SwiftUI.Transaction(plist: []), location: SwiftUI.LocationBox<SwiftUI.(unknown context at $1c5c1c4dc).ObjectLocation<BindingTest.DataManager, Swift.Bool>>, _value: false)
And utilizing var isOnBinding: Binding<Bool>
provides me the identical outcome, binding isn’t being up to date
Binding<Bool>(transaction: SwiftUI.Transaction(plist: []), location: SwiftUI.LocationBox<SwiftUI.FunctionalLocation<Swift.Bool>>, _value: false)
That is only a simplified instance, however I might like to know why 2 variations do not work.
I could make the instance with toggleViewModel
to work if I mark var viewModel: ToggleViewModel
as @Binding
within the ToggleWrapperView
, and take away the @Binding
from the isOn
property of ToggleViewModel
(first instance within the view).
Nevertheless I am making an attempt to have the binding for the isOn
between ToggleViewModel
and DataManager
if attainable.