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
View
as 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
rootView
property to reflect changes in the SwiftUI view. - Embedding: Add
hostingController.view
to 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.view
as 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
UIHostingController
onto aUINavigationController
stack or present it modally.
swiftnavigationController?.pushViewController(hostingController, animated: true)
- Push
Passing Data:
- Pass data to the SwiftUI view via the
rootView
or 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
. UpdaterootView
instead. - Memory Management: Ensure proper management of child view controllers when embedding.
- Interoperability: Use
@Environment
or@ObservedObject
in SwiftUI to communicate with UIKit. - Testing: Test across device sizes and orientations, as
UIHostingController
inherits 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:
UIHostingController
is 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.