-
Use SwiftUI with UIKit
Learn how to take advantage of the power of SwiftUI in your UIKit app. Build custom UICollectionView and UITableView cells seamlessly with SwiftUI using UIHostingConfiguration. We'll also show you how to manage data flow between UIKit and SwiftUI components within your app.
To get the most out of this session, we encourage basic familiarity with SwiftUI.Recursos
- selfSizingInvalidation
- selfSizingInvalidation
- Managing model data in your app
- UIHostingConfiguration
- UIHostingController
- Using SwiftUI with UIKit
- UIViewController
Videos relacionados
WWDC22
WWDC20
-
Buscar este video…
-
-
2:09 - Presenting a UIHostingController
// Presenting a UIHostingController let heartRateView = HeartRateView() // a SwiftUI view let hostingController = UIHostingController(rootView: heartRateView) // Present the hosting controller modally self.present(hostingController, animated: true) -
2:31 - Embedding a UIHostingController
// Embedding a UIHostingController let heartRateView = HeartRateView() // a SwiftUI view let hostingController = UIHostingController(rootView: heartRateView) // Add the hosting controller as a child view controller self.addChild(hostingController) self.view.addSubview(hostingController.view) hostingController.didMove(toParent: self) // Now position & size the hosting controller’s view as desired… -
3:13 - Presenting UIHostingController as a popover
// Presenting UIHostingController as a popover let heartRateView = HeartRateView() // a SwiftUI view let hostingController = UIHostingController(rootView: heartRateView) // Enable automatic preferredContentSize updates on the hosting controller hostingController.sizingOptions = .preferredContentSize hostingController.modalPresentationStyle = .popover self.present(hostingController, animated: true) -
5:27 - Passing data to SwiftUI with manual UIHostingController updates
// Passing data to SwiftUI with manual UIHostingController updates struct HeartRateView: View { var beatsPerMinute: Int var body: some View { Text("\(beatsPerMinute) BPM") } } class HeartRateViewController: UIViewController { let hostingController: UIHostingController< HeartRateView > var beatsPerMinute: Int { didSet { update() } } func update() { hostingController.rootView = HeartRateView(beatsPerMinute: beatsPerMinute) } } -
7:51 - Passing an ObservableObject to automatically update SwiftUI views
// Passing an ObservableObject to automatically update SwiftUI views class HeartData: ObservableObject { @Published var beatsPerMinute: Int init(beatsPerMinute: Int) { self.beatsPerMinute = beatsPerMinute } } struct HeartRateView: View { @ObservedObject var data: HeartData var body: some View { Text("\(data.beatsPerMinute) BPM") } } -
8:30 - Passing an ObservableObject to automatically update SwiftUI views
// Passing an ObservableObject to automatically update SwiftUI views class HeartRateViewController: UIViewController { let data: HeartData let hostingController: UIHostingController<HeartRateView> init(data: HeartData) { self.data = data let heartRateView = HeartRateView(data: data) self.hostingController = UIHostingController(rootView: heartRateView) } } -
9:52 - UIHostingConfiguration
cell.contentConfiguration = UIHostingConfiguration { // Start writing SwiftUI here! } -
11:02 - Building a custom cell using SwiftUI with UIHostingConfiguration
// Building a custom cell using SwiftUI with UIHostingConfiguration cell.contentConfiguration = UIHostingConfiguration { HeartRateTitleView() } struct HeartRateTitleView: View { var body: some View { HStack { Label("Heart Rate", systemImage: "heart.fill") .foregroundStyle(.pink) .font(.system(.subheadline, weight: .bold)) Spacer() Text(Date(), style: .time) .foregroundStyle(.secondary) .font(.footnote) } } } -
12:46 - Building a custom cell using SwiftUI with UIHostingConfiguration
// Building a custom cell using SwiftUI with UIHostingConfiguration cell.contentConfiguration = UIHostingConfiguration { VStack(alignment: .leading) { HeartRateTitleView() Spacer() HeartRateBPMView() } } struct HeartRateBPMView: View { var body: some View { HStack(alignment: .firstTextBaseline) { Text("90") .font(.system(.title, weight: .semibold)) Text("BPM") .foregroundStyle(.secondary) .font(.system(.subheadline, weight: .bold)) } } } -
13:41 - Building a custom cell using SwiftUI with UIHostingConfiguration, with a chart!
// Building a custom cell using SwiftUI with UIHostingConfiguration cell.contentConfiguration = UIHostingConfiguration { VStack(alignment: .leading) { HeartRateTitleView() Spacer() HStack(alignment: .bottom) { HeartRateBPMView() Spacer() Chart(heartRateSamples) { sample in LineMark(x: .value("Time", sample.time), y: .value("BPM", sample.beatsPerMinute)) .symbol(Circle().strokeBorder(lineWidth: 2)) .foregroundStyle(.pink) } } } } -
14:41 - Content margins
cell.contentConfiguration = UIHostingConfiguration { HeartRateBPMView() } .margins(.horizontal, 16) -
15:16 - Cell backgrounds
cell.contentConfiguration = UIHostingConfiguration { HeartTitleView() } .background(.pink) -
16:32 - List swipe actions
cell.contentConfiguration = UIHostingConfiguration { MedicalConditionView() .swipeActions(edge: .trailing) { … } } -
17:25 - Incorporating UIKit cell states
// Incorporating UIKit cell states cell.configurationUpdateHandler = { cell, state in cell.contentConfiguration = UIHostingConfiguration { HStack { HealthCategoryView() Spacer() if state.isSelected { Image(systemName: "checkmark") } } } } -
23:17 - Creating a two-way binding to data in SwiftUI
// Creating a two-way binding to data in SwiftUI class MedicalCondition: Identifiable, ObservableObject { let id: UUID @Published var text: String } struct MedicalConditionView: View { @ObservedObject var condition: MedicalCondition var body: some View { HStack { Spacer() } } }
-