UIHostingController
UIHostingController is a UIKit class introduced in iOS 13 with SwiftUI to bridge SwiftUI views into UIKit-based applications. It allows developers to integrate SwiftUI views into existing UIKit view hierarchies or use them as standalone controllers, enabling a gradual adoption of SwiftUI in legacy apps.
Purpose
- Integration: Embeds SwiftUI views in UIKit apps.
- Interoperability: Facilitates communication between SwiftUI and UIKit components.
- Flexibility: Supports hosting SwiftUI views in navigation stacks, tab bars, or modal presentations.
Key Features
- Root View: Hosts a single SwiftUI
Viewas its root, defined during initialization. - Trait Collection Support: Responds to UIKit trait changes (e.g., size classes, dark mode).
- Lifecycle Management: Manages the lifecycle of the SwiftUI view, aligning with UIKit's view controller lifecycle.
- Customizable: Allows customization of UIKit properties like navigation and presentation styles.
Basic Usage
UIHostingController is initialized with a SwiftUI view and can be used like any other UIViewController.
Example
import SwiftUI
import UIKit
// Define a SwiftUI view
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, SwiftUI!")
.font(.title)
Button("Tap Me") {
print("Button tapped")
}
}
}
}
// Create UIHostingController
let hostingController = UIHostingController(rootView: ContentView())
// Present or push in UIKit
let navigationController = UINavigationController(rootViewController: hostingController)
present(navigationController, animated: true)Key Points
- Initialization: Use
UIHostingController(rootView:)to initialize with a SwiftUI view. - Updating Root View: Update the
rootViewproperty to reflect changes in the SwiftUI view. - Embedding: Add
hostingController.viewto a UIKit view hierarchy or present/push the controller itself.
Common Use Cases
Embedding SwiftUI in UIKit:
- Add a SwiftUI view to a UIKit view hierarchy by adding
hostingController.viewas a subview.
swiftlet hostingController = UIHostingController(rootView: ContentView()) addChild(hostingController) view.addSubview(hostingController.view) hostingController.view.frame = view.bounds hostingController.didMove(toParent: self)- Add a SwiftUI view to a UIKit view hierarchy by adding
Navigation Integration:
- Push
UIHostingControlleronto aUINavigationControllerstack or present it modally.
swiftnavigationController?.pushViewController(hostingController, animated: true)- Push
Passing Data:
- Pass data to the SwiftUI view via the
rootViewor use environment objects.
swifthostingController.rootView = ContentView(data: someData)- Pass data to the SwiftUI view via the
Trait Collection Handling:
- Respond to UIKit trait changes (e.g., size class or dark mode) by updating the SwiftUI view.
swiftoverride func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) hostingController.rootView = ContentView(isDarkMode: traitCollection.userInterfaceStyle == .dark) }
Advanced Features
Environment Customization
Set SwiftUI environment values using UIHostingController's environment method (iOS 15+):
hostingController.rootView = ContentView()
.environment(\.locale, .init(identifier: "en_US"))Sizing Behavior
Control the SwiftUI view's size using preferredContentSize or Auto Layout constraints:
hostingController.preferredContentSize = CGSize(width: 300, height: 200)View Controller Lifecycle
UIHostingController integrates with UIKit's lifecycle methods (viewDidLoad, viewWillAppear, etc.), allowing standard UIKit customizations.
Hosting Configuration (iOS 16+)
Use UIHostingConfiguration for lightweight SwiftUI integration in UIKit cells or views without a full UIHostingController:
cell.contentConfiguration = UIHostingConfiguration {
ContentView()
}Best Practices
- Performance: Avoid frequent reinitialization of
UIHostingController. UpdaterootViewinstead. - Memory Management: Ensure proper management of child view controllers when embedding.
- Interoperability: Use
@Environmentor@ObservedObjectin SwiftUI to communicate with UIKit. - Testing: Test across device sizes and orientations, as
UIHostingControllerinherits UIKit's trait system.
Limitations
- Performance Overhead: Embedding SwiftUI in UIKit can be less performant than native UIKit or SwiftUI apps.
- Complexity: Mixing paradigms requires careful state management to avoid inconsistencies.
- Backward Compatibility:
UIHostingControlleris available only on iOS 13 and later.
Summary
UIHostingController is a powerful tool for integrating SwiftUI into UIKit apps, enabling developers to leverage SwiftUI's declarative syntax while maintaining compatibility with existing UIKit codebases. It supports a range of use cases, from embedding small SwiftUI components to hosting full-screen SwiftUI views, with robust support for UIKit's navigation and trait systems.