1

Just started a journey with SwiftUI and realised that for some reason there're a lot of components from UIKit which must be wrapped in UIViewControllerRepresentable to be working in SwiftUI code. One of them should react to change of the @State/@Binding param which is changed in a separate component. The issue is I need somehow to subscribe to that state param and handle its updates in wrapper struct. But I could not find any Binding<> props which could allow doing that.

There's a simple example

struct SwiftUIView: View {
    @State private var state:Bool = false
    var body: some View {
        Foo(state: self.$state)
    }
}

struct Foo<Content: View>: UIViewControllerRepresentable {
    var state: Binding<Bool>
    init(state: Binding<Bool>) {
        self.state = state
        // how to watch this param and handle every change by calling bar function?
    }

    func bar(newState: Bool) {
        print(newState)
    }
    func makeUIViewController() {}
    func updateUIViewController() {}
}

Probably there should be another approach?

4
  • 1
    Hmm, I think more details are needed for what you actually want to accomplish. One way is to make Foo an ObservableObject and declare the state there, then use it in the View. You can use a didSet block on the state in the observable object and call the function. Commented Nov 20, 2019 at 15:22
  • Ok, imagine Foo struct implements UIViewControllerRepresentable and wraps UIScrollViewViewController for UIScrollView component and I'd like to pass page state in this struct to control position of UIScrollView How can I do it? PS code has been updated Commented Nov 20, 2019 at 15:32
  • Then this should be handled in the updateUIViewController function. You would have something like this: @Binding var state: Bool and func updateUIViewController() { bar(newState: state) } Commented Nov 20, 2019 at 15:51
  • 1
    Ok, great. Thank you! Commented Nov 20, 2019 at 18:27

1 Answer 1

2

I show you a workable example. You can get a naturally updated binding value like this.

struct SwiftUIView: View {
    @State private var state: Bool = false
    
    var body: some View {
        Group {
            Button(action: {
                self.state.toggle()
            }, label: { Text("Text Button") })
            Foo(state: self.$state)
        }
    }
}

struct Foo: UIViewRepresentable {
    var state: Binding<Bool>

    func bar(newState: Bool) {
        print(newState)
    }

    func makeUIView(context: UIViewRepresentableContext<Foo>) -> UIView {
        let vc = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100))
        vc.backgroundColor = UIColor.red
        return vc
    }

    func updateUIView(_ uiViewController: UIView, context: UIViewRepresentableContext<Foo>) {
        bar(newState: self.state.wrappedValue)
    }
}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.