I have a SwiftUI
view that works as expected in a full SwiftUI
context. But I now need to use it in a UIViewController.
It mostly works, but I'm trying to expose an @State var
out to the viewController,
and it only ever returns the initial value.
Any guidance for how best to pass out this @State var?
I could make it be a binding, but in my pure SwiftUI
code, it works fine as @State
(ie EditorView
's container view does not need to know about sliderVal
)
thanks, in advance, for any suggestions
import SwiftUI
import UIKit
class ViewController: UIViewController {
var host: UIHostingController<EditorView>?
override func viewDidLoad() {
super.viewDidLoad()
host = .init(rootView: EditorView())
guard let host = host else { return }
addChild(host)
host.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(host.view)
host.didMove(toParent: self)
}
@IBAction func helloTapped(sender: UIButton) {
guard let sliderValue = host?.rootView.sliderVal else { return }
print("UIKit sliderValue: \(sliderValue)")
}
}
struct EditorView: View {
@State var sliderVal: Double
init(sliderVal: Double? = nil) {
_sliderVal = State(initialValue: sliderVal ?? 7)
}
var body: some View {
VStack {
Slider(value: $sliderVal, in: 1...10)
Text("sliderVal: \(sliderVal)")
}
}
}
(NOTE: in order to see this code snippet in action you will need to create a button in the storyboard and link it to helloTapped
)
@mikeTheDad You should review Using SwiftUI with UIKit sample project to learn how to incorporate SwiftUI views into a UIKit app. Using the @ObservedObject
property wrapper as @JimmyCricket suggested in this case ensures that SwiftUI automatically refresh the view when any of the @Published
properties of the ObservableObject
change, and also allows a binding to be created so that SwiftUI can write back changes to that property when the slider value changes