View controllers are not just for the top level scene. We often place view controllers within view controllers. It’s called “view controller containment” and/or “child view controllers”. (BTW, view controller containers are, in general, a great way to fight view controller bloat in traditional UIKit apps, breaking complicated scenes into multiple view controllers.) 
So,
- Go ahead and use - UIHostingController:
 - let controller = UIHostingController(rootView: ...)
 - and; 
- Add the view controller can then add the hosting controller as a child view controller: - addChild(controller)
view.addSubview(controller.view)
controller.didMove(toParent: self)
 - Obviously, you’d also set the - frameor the layout constraints for the hosting controller’s- view.
 - See the Implementing a Container View Controller section of the - UIViewControllerdocumentation for general information about embedding one view controller within another.
 
For example, let’s imagine that we had a SwiftUI View to render a circle with text in it:
struct CircleView : View {
    @ObservedObject var model: CircleModel
    var body: some View {
        ZStack {
            Circle()
                .fill(Color.blue)
            Text(model.text)
                .foregroundColor(Color.white)
        }
    }
}
And let’s say this was our view’s model:
import Combine
class CircleModel: ObservableObject {
    @Published var text: String
    init(text: String) {
        self.text = text
    }
}
Then our UIKit view controller could add the SwiftUI view, set its frame/constraints within the UIView, and update its model as you see fit:
import UIKit
import SwiftUI
class ViewController: UIViewController {
    private weak var timer: Timer?
    private var model = CircleModel(text: "")
    override func viewDidLoad() {
        super.viewDidLoad()
        addCircleView()
        startTimer()
    }
    deinit {
        timer?.invalidate()
    }
}
private extension ViewController {
    func addCircleView() {
        let circleView = CircleView(model: model)
        let controller = UIHostingController(rootView: circleView)
        addChild(controller)
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(controller.view)
        controller.didMove(toParent: self)
        NSLayoutConstraint.activate([
            controller.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
            controller.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5),
            controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }
    func startTimer() {
        var index = 0
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
            index += 1
            self?.model.text = "Tick \(index)"
        }
    }
}