HomeiOS Developmentios - SwiftUI Binding property inside view mannequin

ios – SwiftUI Binding property inside view mannequin


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.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments