This is my first time working in Xcode and I am building an app using Storyboards/View Controllers. However, I have a page I want to display using SwiftUI, which I am doing through a host controller. I want to be able to assign a value to a variable in my ViewController code and then access this value in my swiftUI ContentView file. I feel like there should be a simple solution, but I can't seem to find a way to share data between the two. Thank you for any help.
2 Answers
Here is a simple method to see how to pass data to SwiftUI View from
UIKit UIViewController. Here I'm passing a simple text setting it in the initializer of ContentView and presenting the UIHostingController on ViewController. Here is the code:
import UIKit
import SwiftUI
import PlaygroundSupport
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(action))
}
@objc func action() {
let contentView = ContentView(text: "My Text")
let viewController = UIHostingController(rootView: contentView)
present(viewController, animated: true)
}
}
struct ContentView: View {
var text: String
var body: some View {
Text(text)
}
}
PlaygroundPage.current.setLiveView(UINavigationController(rootViewController: ViewController()))
PlaygroundPage.current.needsIndefiniteExecution = true
You can copy/paste this code on your playground to see how it works.
Comments
Assuming you are using a UIHostingController and a story board segue, you can use the prepare for segue function to set a value in the rootView of the hosting view controller.
For example:
UIViewController
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "theSegue" {
let dest = segue.destination as! TheHostingViewController
dest.rootView.theString = "This is the String to pass"
}
}
}
UIHostingController
import UIKit
import SwiftUI
class TheHostingViewController: UIHostingController<TheSwiftUIView> {
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder, rootView: TheSwiftUIView())
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
SwiftUI view
import SwiftUI
struct TheSwiftUIView: View {
var theString: String?
var body: some View {
Text(theString!)
}
}
Be sure to change the Class of the Hosting Controller to the name of your UIHostingController in interface builder (as shown in the image below).

