I want to pass a binding of a @Published
variable from within my ObservableObject
to a struct so that its value can be changed inside a closure. I can't quite get it to work. Here is a simplified version of my code below:
final class OnboardingStateController: ObservableObject {
@Published var shouldHide: Bool = false
func go() {
MyLogic.fooBar(
shouldHide: shouldHide // error appears here Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'
)
}
}
struct MyLogic {
static func fooBar(shouldHide: Binding<Bool>) {
... SomeClass({ shouldHide.wrappedValue = true })
}
}
How do I do this?
CodePudding user response:
Here is an alternative, Binding
needs a SwiftUI View
to stay updated because of its DynamicProperty
conformance
import SwiftUI
struct OnboardingStateView: View {
@StateObject var vm: OnboardingStateController = OnboardingStateController()
var body: some View {
VStack{
Button("go", action: {
vm.go()
})
Text(vm.shouldHide.description)
}
}
}
final class OnboardingStateController: ObservableObject {
@Published var shouldHide: Bool = false
func go() {
//This uses a completion handler vs passing the `Binding`
MyLogic.fooBar(
shouldHide: { shouldHide in
self.shouldHide = shouldHide
}
)
}
}
struct MyLogic {
static func fooBar(shouldHide: (Bool) -> Void) {
let value = Bool.random() //.. SomeClass({ shouldHide.wrappedValue = true })
shouldHide(value)
}
}
struct OnboardingStateView_Previews: PreviewProvider {
static var previews: some View {
OnboardingStateView()
}
}
CodePudding user response:
It is not really clear why do you need Binding
there, but if it is really still needed there, then you can generate it on the fly, like
func go() {
MyLogic.fooBar(
shouldHide: Binding(get: { self.shouldHide }, set: { self.shouldHide = $0 })
)
}
Note: it is simplified variant, in which self
is captured, if you need to avoid it then you take into account using [weak self]
in each closure.