Include SwiftUI views in existing UIKit application Include SwiftUI views in existing UIKit application swift swift

Include SwiftUI views in existing UIKit application


edit 05/06/19: Added information about UIHostingController as suggested by @Departamento B in his answer. Credits go to him!


Using SwiftUI within UIKit

One can use SwiftUI components in existing UIKit environments by wrapping a SwiftUI View into a UIHostingController like this:

let swiftUIView = SomeSwiftUIView() // swiftUIView is Viewlet viewCtrl = UIHostingController(rootView: swiftUIView)

It's also possible to override UIHostingController and customize it to one's needs, e. g. by setting the preferredStatusBarStyle manually if it doesn't work via SwiftUI as expected.

UIHostingController is documented here.


Using UIKit within SwiftUI

If an existing UIKit view should be used in a SwiftUI environment, the UIViewRepresentable protocol is there to help! It is documented here and can be seen in action in this official Apple tutorial.


Compatibility

Please note that you cannot use SwiftUI on iOS versions < iOS 13, as SwiftUI is only available on iOS 13 and above. See this post for more information.

If you want to use SwiftUI in a project with a target below iOS 13, you need to tag your SwiftUI structs with @available(iOS 13.0.0, *) attribute.


If you want to embed SwiftUI into a UIKit view controller, use a Container View.

class ViewController: UIViewController {    @IBOutlet weak var theContainer: UIView!    override func viewDidLoad() {        super.viewDidLoad()        let childView = UIHostingController(rootView: SwiftUIView())        addChild(childView)        childView.view.frame = theContainer.bounds        theContainer.addSubview(childView.view)        childView.didMove(toParent: self)    }}

Reference


UIHostingController

Although at the moment the documentation for the class has not been written, UIHostingController<Content> seems to be what you're looking for: https://developer.apple.com/documentation/swiftui/uihostingcontroller

I've just tried it in my app with the following line of code:

let vc = UIHostingController(rootView: BenefitsSwiftUIView())

Where BenefitsSwiftUIView is just the default "Hello World" View from SwiftUI. This works exactly as you expect it. It also works if you subclass UIHostingController.